Skip to content

Conversation

@vmednis
Copy link

@vmednis vmednis commented Jan 13, 2026

#pragma once is widely supported, but it is not part of the C standard and not all C toolchains recognize it. To improve portability, this adds traditional include guards alongside the existing #pragma once.

I ran into issues using the headers in a Zig project with @cInclude, which were resolved after adding the guards. Similar problems have been reported with older versions of TCC (Fixes #466).

#pragma once is kept to preserve existing behavior and potential compile-time benefits on compilers that support it.

These changes don’t affect the ABI or public API and only make header inclusion more reliable across different toolchains.

@CLAassistant
Copy link

CLAassistant commented Jan 13, 2026

CLA assistant check
All committers have signed the CLA.

@abique
Copy link
Contributor

abique commented Jan 13, 2026

Is there an issue for Zig not supporting #pragma once?

@vmednis
Copy link
Author

vmednis commented Jan 13, 2026

Similar issues with #pragma once have been reported in multiple toolchains — for example, older versions of TCC fail to compile the headers correctly (see #466).

No issue currently exists for this in Zig; however, in my own testing, including the headers from Zig using @cInclude on master produces endless redefinition errors, whereas it works correctly on Zig 0.15.1:

const clap = @cImport({
    @cInclude("/.../clap/include/clap/clap.h");
});
const expect = @import("std").testing.expect;

test "check if include was successful" {
    const version: clap.clap_version = clap.CLAP_VERSION;
    try expect(version.major == 1);
    try expect(version.minor == 2);
    try expect(version.revision == 7);
}

The lack of #pragma once support in Zig appears to be a regression on their side. I will raise an issue with Zig, but still, adding standard include guards makes the headers more portable and standards-compliant, which I believe is still beneficial for a project like CLAP.

@baconpaul
Copy link
Collaborator

I would personally be supportive of removing pragma once from all our codebases, just FYI alex. I agree that its not standard.

@abique
Copy link
Contributor

abique commented Jan 15, 2026

It's not clear what it fixes, tcc now supports pragma once apparently, and zig did, it is just a temporary regression, which could be worked around by using the previous version until they fix it.

I don't like traditional header guard, I think it is worse than #pragma once in every aspects, except that it is part of the standard; yet I would not be surprised if we learn that other parts of the macro processor standard are not implemented by tcc or zig.

I don't want to maintain this stuff, so if it gets out of sync or whatever, someone else will have to make a PR.
Also I won't add that myself to clap-helpers as well, so if that becomes requested one day, someone else will have to make a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

replace pragma once with include guards

4 participants