OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 2:17 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: C Header File conventions
PostPosted: Fri Oct 14, 2022 1:27 am 
Offline
User avatar

Joined: Tue Jun 14, 2022 1:37 am
Posts: 2
I'm following along the meaty skeleton tutorial and had a few questions about the header file conventions used. Unfortunately, seems the account that created it is no longer active, so I'm hoping others are aware of the conventions being used.

I see three distinct conventions used on the include guards in this tutorial, they are:
  • all caps version of the filename, including extension
  • all caps name including preceding underscore and library name (e.g. "_KERNEL_TTY_H")
  • the second convention, but with the define having a "1" after the guard name

For anyone who's viewing this thread in hopes of learning about the conventions, here's an explanation of the first two. The first rule is fairly standard, by naming your preprocessor guard like this, you avoid naming conflicts with other headers. The second rule is used since that particular header is being compiled as part of libc, and convention holds that global headers have this preceding underscore to further avoid conflict with project specific headers. If anyone has any corrections or clarifications on this, please let me know.

My question is mostly about the third rule I listed. Why is the "1" following the define? The author of that page said most elements of their code is intentional, even the weirder ones, as they either directly serve a purpose for the tutorial, or help to simplify future work. I tried searching for this convention but could not find anything about it.


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Tue Oct 18, 2022 2:43 am 
Offline
Member
Member
User avatar

Joined: Mon Mar 05, 2012 11:23 am
Posts: 616
Location: Germany
There is no further intention behind this. #ifndef will only check if the symbol is (not) defined, the value does not matter.

_________________
Ghost OS - GitHub


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Tue Oct 18, 2022 4:53 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7612
Location: Germany
lortega wrote:
The second rule is used since that particular header is being compiled as part of libc, and convention holds that global headers have this preceding underscore to further avoid conflict with project specific headers. If anyone has any corrections or clarifications on this, please let me know.


Any kind of identifier that begins with two underscores, or one underscore and an uppercase letter, is "reserved for the implementation", i.e. not legal in application code. (There are more reserved identifiers, like E_*, but they are reserved for different purposes.)

"The implementation" used to be the combination of compiler and library. Since compiler and library could conceivably come from two different upstreams, you have to "hope" that they don't use the same identifier for different things. Prefixing identifiers with _MYCLIB_* or _MYCOMPILER_* reduces that probability to next-to-zero.

lortega wrote:
My question is mostly about the third rule I listed. Why is the "1" following the define?


Safeguard against being lazy. It makes no difference for #ifdef / #ifndef, but if you just wrote #if, having the identifier defined to 1 will give you a true result, while having it defined to empty will give you a somewhat funky error message.

There's yet another convention, that is to define the header guard to itself.

Code:
#ifndef MYAPP_MAIN_H
#define MYAPP_MAIN_H MYAPP_MAIN_H


In the (admittedly far-fetched) case that someone wanted to use MYAPP_MAIN_H as a variable or function name, both "#define MYAPP_MAIN_H" and "#define MYAPP_MAIN_H 1" would cause a compilation error, while the above construct doesn't.

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Tue Oct 18, 2022 7:13 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
Excellent explanation.

But it would be more consistent to stick to one convention (use 1 everywhere or use 1 nowhere) rather than mixing styles.


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Tue Oct 18, 2022 10:36 am 
Offline
Member
Member

Joined: Mon Feb 02, 2015 7:11 pm
Posts: 898
Here is another convention:
Code:
#pragma once

Although 'non-standard", it is effectively supported by all compilers.

_________________
https://github.com/kiznit/rainbow-os


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Tue Oct 18, 2022 1:26 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1593
kzinti wrote:
Although 'non-standard", it is effectively supported by all compilers.
I would disagree. It is not supported by at least one compiler I use regularly, and that is one more than has an issue with normal include guards. Clang, GCC, and MSVC make up a large chunk of the compiler market, but they are not all of it.

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Tue Oct 18, 2022 3:03 pm 
Offline
Member
Member

Joined: Mon Feb 02, 2015 7:11 pm
Posts: 898
Not many people get to work on OS-9. Lucky you.

_________________
https://github.com/kiznit/rainbow-os


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Tue Oct 18, 2022 3:13 pm 
Offline
User avatar

Joined: Tue Jun 14, 2022 1:37 am
Posts: 2
Wow thanks everyone so many quick responses! Glad to see its just a separate convention and not some alternate functionality I was missing. In that case, I'll do what makes the most sense to me and was suggested in this thread, and go along with using the same style (so no "1" for me). I understand it helps if someone uses #if rather than #ifdef, but thats not something I would personally use nor any collaborators I can think of, so seems to make more sense just to stick to a programming style that makes the most sense for me.


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Tue Oct 18, 2022 9:15 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1593
kzinti wrote:
Not many people get to work on OS-9. Lucky you.
I feel so privileged.

...he said, bitterly, as he waited another five minutes for the bloody prelinker to finish.

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Wed Oct 19, 2022 2:32 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7612
Location: Germany
kzinti wrote:
Here is another convention:
Code:
#pragma once

Although 'non-standard", it is effectively supported by all compilers.


And I've run into problems with that at least twice (once in the context of softlinked header files, once in the context of a header file being copied into several locations of the source tree). I don't really get why anyone would go for a #pragma of any kind for something that can be done perfectly well without.

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Wed Oct 19, 2022 4:07 am 
Offline
Member
Member

Joined: Mon Feb 02, 2015 7:11 pm
Posts: 898
Solar wrote:
once in the context of softlinked header files

Yes I can see how that could be a problem... As I understand it GCC and clang both handle them properly.

Solar wrote:
once in the context of a header file being copied into several locations of the source tree).

Your problem here is that you copied the same header file in several locations, not that you used #pragma once. You could also run into issues with #ifdef/#define if you modified one of these file and forgot to update the other locations. Did you end up copying the file because of the softlink issue above?

Solar wrote:
I don't really get why anyone would go for a #pragma of any kind for something that can be done perfectly well without.

- Can reduce build time as the compiler doesn't need to open and read the same file again after the first #include of the file in the translation unit.
- Doesn't pollute the global namespace with header guards
- Less error prone
- Less maintenance on the programmer's part

In my experience, I've run into problems with header guards a few times where I've only hit one issue with #pragma once: a compiler that didn't support it in a cross-platform project.

More info here: https://en.wikipedia.org/wiki/Pragma_once

_________________
https://github.com/kiznit/rainbow-os


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Wed Oct 19, 2022 8:56 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7612
Location: Germany
kzinti wrote:
Solar wrote:
once in the context of a header file being copied into several locations of the source tree).

Your problem here is that you copied the same header file in several locations, not that you used #pragma once. You could also run into issues with #ifdef/#define if you modified one of these file and forgot to update the other locations. Did you end up copying the file because of the softlink issue above?


The issue was that the developer thought that "same file name, same contents" would make the compiler consider it the same file and thus avoid redeclaration / redefinition issues. Whereas the compiler considered those separate files.

You're losing a level of control with #pragma once.

kzinti wrote:
Solar wrote:
I don't really get why anyone would go for a #pragma of any kind for something that can be done perfectly well without.

- Can reduce build time as the compiler doesn't need to open and read the same file again after the first #include of the file in the translation unit.


GCC does not re-read header files since at least version 3.0...

kzinti wrote:
- Less error prone


To the contrary, which was the reason for my comment. I despise "automagic" solutions to non-existing problems, because when those go awry, finding out what your actual problem is can be orders of magnitude more annoying than e.g. a mistyped header guard.

(Have you ever had a hash collision in a Git repository? I have. No fun.)

kzinti wrote:
In my experience, I've run into problems with header guards a few times...


All of which boil down to developer error, not compiler quirk...

kzinti wrote:
...where I've only hit one issue with #pragma once: a compiler that didn't support it in a cross-platform project.


Well, cross-platform is pretty much all I am doing, and in some cases with some really old compiler. (Dice C on the Amiga.)

kzinti wrote:


Gee, look at the "Caveat" section! Pretty much exactly what I wrote above! :D

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Wed Oct 19, 2022 10:21 am 
Offline
Member
Member

Joined: Mon Feb 02, 2015 7:11 pm
Posts: 898
You got me thinking and now I don't think one method is (much) better than the other. They both have pros and cons. I just wanted to bring it up as another option since this was the subject of this thread.

_________________
https://github.com/kiznit/rainbow-os


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Fri Oct 21, 2022 5:54 pm 
Offline
Member
Member

Joined: Tue Apr 03, 2018 2:44 am
Posts: 401
I use makeheaders, from the same guy that wrote SQLite.

Makes header management a breeze. Each source file has a single header (plus any compiler/system headers required), and that single head is generated from the sources.

If one source file references a function defined in another source file, that function is prototyped and inserted into the source's header file. It makes my C source really easy to manage.


Top
 Profile  
 
 Post subject: Re: C Header File conventions
PostPosted: Mon Oct 24, 2022 8:22 am 
Offline
Member
Member
User avatar

Joined: Mon May 22, 2017 5:56 am
Posts: 812
Location: Hyperspace
Some years ago I read that slow compilation was considered one of C++'s bigger problems, and that re-including header files was part of the reason it was so slow. Guards don't really help with this; the preprocessor still has to parse the entire file every time its loaded to find the correct #endif. I assume #pragma once is an attempt to deal with this speed issue. That's the only positive thing I have to say about it, anyway.

_________________
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 37 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group