27 Jan 2023 |
GalacticColourisation | because pragma once has annoying bugs | 20:23:44 |
Raph | yeah seems like in this server include guards are more used when I learned about #pragma once the I decided to continue using include guards bc it was the only one that was actually standardized | 20:23:58 |
Mane | Such as? | 20:24:13 |
Raph | what about the definition collision issue with include guards? pragmas don't have that issue and on compilers that aren't very smart if they implement pragma once they'll compile faster | 20:25:01 |
GalacticColourisation | https://en.m.wikipedia.org/wiki/Pragma_once https://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards | 20:26:55 |
Raph | https://en.wikipedia.org/wiki/Pragma_once | 20:27:57 |
Raph | I like this one better | 20:28:01 |
Raph | check the caveats section | 20:28:07 |
GalacticColourisation | #pragma once has unfixable bugs. It should never be used.
If your #include search path is sufficiently complicated, the compiler may be unable to tell the difference between two headers with the same basename (e.g. a/foo.h and b/foo.h), so a #pragma once in one of them will suppress both. It may also be unable to tell that two different relative includes (e.g. #include "foo.h" and #include "../a/foo.h" refer to the same file, so #pragma once will fail to suppress a redundant include when it should have.
This also affects the compiler's ability to avoid rereading files with #ifndef guards, but that is just an optimization. With #ifndef guards, the compiler can safely read any file it isn't sure it has seen already; if it's wrong, it just has to do some extra work. As long as no two headers define the same guard macro, the code will compile as expected. And if two headers do define the same guard macro, the programmer can go in and change one of them.
#pragma once has no such safety net -- if the compiler is wrong about the identity of a header file, either way, the program will fail to compile. If you hit this bug, your only options are to stop using #pragma once, or to rename one of the headers. The names of headers are part of your API contract, so renaming is probably not an option. | 20:28:10 |
GalacticColourisation | the only 2 advantages pragma once has is that its faster to compile (its C, you dont need faster compilation speed so this is useless (well its already useless since the difference in speed is barely noticable anyways)) and the second is that its shorter | 20:29:45 |
GalacticColourisation | but otherwise theres tons of caveats to it compared to include guards | 20:30:02 |
Raph | I've seen some people that straight up use
#pragma once
#ifndef HEADER_H
#define HEADER_H
// header implementation
#endif | 20:30:32 |
GalacticColourisation | thats other than the fact that some embedded compilers dont implement #pragma once because theyre not standardised so you'll still have issues | 20:30:39 |
Mane | https://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards
This link has opinions and "fact"s that contradict each other, all over the place. Don't know who to trust in that situation.
https://en.wikipedia.org/wiki/Pragma_once#Caveats
This one is more objective, and an interesting read. | 20:31:13 |
GalacticColourisation | the one by the gcc maintainer | 20:31:32 |
Mane | In the end, simply using unique names for your include guards stays the best option. | 20:31:43 |
GalacticColourisation | or the ex-maintainer | 20:32:08 |
Mane | Anyone that would guard a file that is supposed to be used by the public with a basic name is failing in advance. | 20:32:43 |
Raph | yeah probably religiously abiding by standards is the best option in C/C++ I feel like | 20:32:46 |
GalacticColourisation | but anyways, its not like the issues that pragma once has arent common in C, they very much are | 20:32:50 |
Mane | Religiously is a strong word, not to mention, which standard exactly? | 20:33:07 |
Raph | any of the standards, C99 or newere | 20:33:19 |
Raph | * any of the standards, C99 or newer | 20:33:22 |
Mane | It changes based on what you're working on, some embedded standards are especially rigorous even when they don't need to be. | 20:33:35 |
Raph | I've never had a reason to use another compiler tbh | 20:34:27 |
Raph | I just use gcc or clang | 20:34:32 |
Raph | I just use -std=c11 or something and make sure to avoid language extensions | 20:34:52 |
Raph | so I have no idea about platform specific compilers made by vendors or anything | 20:35:22 |
Raph | well besides arduino, if that even counts | 20:35:34 |
Mane | I guess? | 20:36:49 |