gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > #include "something.c"

#112650 - tepples - Tue Dec 19, 2006 5:30 am

In this post, DekuTree64 wrote:
And if you can only safely include the header in one .c file, then there's no point in it being a header in the first place, rather than just being part of the .c file itself.

Unless the header file is generated by another program that precomputes a lookup table, and you don't want a separate .o file for each lookup table.

Topic was split at this point.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.


Last edited by tepples on Wed Dec 20, 2006 1:42 am; edited 1 time in total

#112653 - DekuTree64 - Tue Dec 19, 2006 6:03 am

tepples wrote:
DekuTree64 wrote:
And if you can only safely include the header in one .c file, then there's no point in it being a header in the first place, rather than just being part of the .c file itself.

Unless the header file is generated by another program that precomputes a lookup table, and you don't want a separate .o file for each lookup table.

For that sort of thing I name the include files .inc to make it obvious that they're not regular headers.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#112677 - kusma - Tue Dec 19, 2006 11:18 am

DekuTree64 wrote:
tepples wrote:
DekuTree64 wrote:
And if you can only safely include the header in one .c file, then there's no point in it being a header in the first place, rather than just being part of the .c file itself.

Unless the header file is generated by another program that precomputes a lookup table, and you don't want a separate .o file for each lookup table.

For that sort of thing I name the include files .inc to make it obvious that they're not regular headers.


...and loose syntax-highlighting in most editors?

#112679 - wintermute - Tue Dec 19, 2006 11:53 am

Any decent editor will let you specify the syntax highlighting per extension.

Personally I don't see any particular problem with having an object file per lookup table/generated data. You can always put your data in a library archive if it bothers you too much.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#112680 - kusma - Tue Dec 19, 2006 12:16 pm

wintermute wrote:
Any decent editor will let you specify the syntax highlighting per extension.


Yes, but how do you differentiate between include-files for different languages? Besides, this is something that everyone who works on a project would have to setup manually to get decent readability of the code - not very optimal IMO.

I agree that data in headers is a bad idea in general, but I do find myself using it in some case. One example would be the LUTs used in Pimpmobile. Those are generated by a Python-script, and only included into one source-file. Perhaps prefixing the filename with something like "internal_" would make it clearer that it isn't for normal inclusion?

#112756 - poslundc - Wed Dec 20, 2006 12:28 am

kusma wrote:
Yes, but how do you differentiate between include-files for different languages? Besides, this is something that everyone who works on a project would have to setup manually to get decent readability of the code - not very optimal IMO.


Neither is rebuilding all of your data tables whenever just one of them changes.

Or dealing with link errors when the file gets accidentally included in some other module.

Or dealing with programmers on your team or other teams who develop bad habits and start putting data tables everywhere because they can't see the distinction between what they're doing and what you're doing.

Quote:
I agree that data in headers is a bad idea in general, but I do find myself using it in some case. One example would be the LUTs used in Pimpmobile. Those are generated by a Python-script, and only included into one source-file. Perhaps prefixing the filename with something like "internal_" would make it clearer that it isn't for normal inclusion?


No matter what way I ponder it I always come back to the same question: why are you trying to force them all to be included into one file in the first place? It's simply a less scalable technique than having separate compilation units.

Dan.

#112769 - tepples - Wed Dec 20, 2006 1:41 am

poslundc wrote:
No matter what way I ponder it I always come back to the same question: why are you trying to force them all to be included into one file in the first place? It's simply a less scalable technique than having separate compilation units.

It could be a holdover from the days when the default %COMSPEC% shell generally limited a command line to 128 characters, requiring compiler vendors to implement workarounds in libc that were generally incompatible from vendor to vendor. It could also be a holdover from the FAT16 and HFS days when a single file filled 16 KB of a 1 GB drive even if it had only 1 KB of data. And it could be an accommodation for underpowered build hardware that has to reread and reparse a megabyte of actual header files (#include <windows.h> anyone?) for each separate source file.

Split time.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#112776 - DekuTree64 - Wed Dec 20, 2006 2:21 am

One example situation that I might use .inc files for is if I have a table of tables that I need to edit by hand, and the child tables are too large to manage in a single file.
You could just compile the child table files individually, but then you'd have to extern all of them in the parent table file, even though they're really supposed to be static to that file in the first place (assuming there are multiple tables within each include file. Otherwise #including would be no less hassle than externing).

But generally if I have a bunch of related tables that aren't too large (such as note frequency/pitch slide/etc. tables for music players), I just paste them into a single file even if they were originally autogenerated as seperate files by different tools. This is just my personal preference though, that if I won't actually be looking at/editing entries in the tables, I'd rather not have a bunch of files cluttering things up.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#112777 - sajiimori - Wed Dec 20, 2006 3:05 am

Right, I also sometimes use .inc files for autogenerated tables that are supposed to be local to a file. It can also simplify the autogenerator code.
Code:

   // Autogenerator can just do a comma-separated list.
   static const u32 kRemoteFiles[] =
   {
      #include "RemoteFiles.inc"
   };

#112787 - sgeos - Wed Dec 20, 2006 5:55 am

I don't see the point of putting everything in one file. In any large project you'll be dealing with thousands of files anyway. Get used it. Many, many files become final product.

-Brendan

#112799 - kusma - Wed Dec 20, 2006 11:06 am

poslundc wrote:
No matter what way I ponder it I always come back to the same question: why are you trying to force them all to be included into one file in the first place? It's simply a less scalable technique than having separate compilation units.


Who sais all data files are included into the same compilation unit? It's included wherever it's appropriate.

#112840 - poslundc - Wed Dec 20, 2006 7:53 pm

kusma wrote:
poslundc wrote:
No matter what way I ponder it I always come back to the same question: why are you trying to force them all to be included into one file in the first place? It's simply a less scalable technique than having separate compilation units.


Who sais all data files are included into the same compilation unit? It's included wherever it's appropriate.


So you are replicating your entire data table in each file that references it? Does that seem like a good idea?

Dan.

#112880 - sajiimori - Thu Dec 21, 2006 1:28 am

I think, Dan, that we are running into English language limitations.

"All .inc files are included in a single file" could mean that there is one module that includes all .inc files, or that for each .inc file there is exactly one module that includes it. The latter interpretation makes much more sense.

A statement like "The .inc file is included wherever it's appropriate" does not imply that it's included in multiple modules. It's quite appropriate to include it in a single, appropriately-chosen module.

#112936 - poslundc - Thu Dec 21, 2006 7:46 pm

sajiimori wrote:
A statement like "The .inc file is included wherever it's appropriate" does not imply that it's included in multiple modules. It's quite appropriate to include it in a single, appropriately-chosen module.


Yes, so long as they are singularly included then that's fine. I still think it's misleading and dangerous to use the header .h extension for those kinds of files, though.

Dan.

#113196 - Ultima2876 - Sun Dec 24, 2006 10:10 am

If there's thousands of .c files, how the hell long is it going to take you to compile the project? It'd take years just to type the command o_O

#113215 - wintermute - Sun Dec 24, 2006 2:33 pm

Ultima2876 wrote:
If there's thousands of .c files, how the hell long is it going to take you to compile the project? It'd take years just to type the command o_O


That's why we use makefiles and libraries.

devkitARM takes a couple of hours to build from scratch on a recent PC and approaches some 15000 files in the source tree.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#113227 - gmiller - Sun Dec 24, 2006 7:31 pm

If you have a good make file then you don't need to type anything other than "make". And if your data is in it's own object file it only needs to be linked unless the data has been modified.

#113415 - Ultima2876 - Wed Dec 27, 2006 6:00 pm

But don't you have to modify the makefile each time you add a new source file?

I'd understand if I'm wrong about this though, I don't know much about makefiles.

#113416 - kusma - Wed Dec 27, 2006 6:07 pm

Ultima2876 wrote:
But don't you have to modify the makefile each time you add a new source file?

I'd understand if I'm wrong about this though, I don't know much about makefiles.


Usually you do, yeah. But you shouldn't be afraid of modifying you Makefiles ;)

#113426 - gmiller - Wed Dec 27, 2006 7:58 pm

Depending on what you do in your make file you can set on up to auto-magicly adjust to new files. I have mine set up to look for all of the source files (.c, .s, .cpp) in the source directory and build dependencies and them compile. The default is arm mode and using the appropriate compilers/assembler in thumb mode. If the file is .arm.c, .arm.cpp, .arm.s them the code will be in ARM mode instead of Thumb mode. This makes adding new files just dropping them into the correct folder and then type "make". I does mean that if you leave a file in the folder then you might link in extra but it works pretty good. This is not a method that I have seen many people use but it works for me.

#113433 - kusma - Wed Dec 27, 2006 8:10 pm

gmiller wrote:
This is not a method that I have seen many people use but it works for me.


I've tried it, and decided not to continue with it or regular projects, simply because it's too often i want to exclude source files from projects for various reasons.

#113437 - tepples - Wed Dec 27, 2006 8:35 pm

Specifically, I want to exclude Allegro-only source code files in a GBA build, GBA-only source code files in an Allegro (Windows, Mac, or Linux) build, and Windows-only source code files (e.g. the resource compiler script that inserts a .exe icon) in an Allegro build on Mac or Linux.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#113448 - gmiller - Wed Dec 27, 2006 9:23 pm

I have #ifdef's for platform specific code in files. I understand that this is a trade off but I have some files where I have platform specific forms of a particular function and I like all of the variants in the same file for ease of porting. This is one of those "choose what works for you" decisions but seeing what others do can help you make a more flexible decision.

#113449 - sajiimori - Wed Dec 27, 2006 9:36 pm

Manually maintaining lists of source files is a minor waste of time.
Code:

SRC_DIRS = Actors IO Physics Main

ifeq($(BUILD_TYPE), GBA)
  SRC_DIRS += GBARenderer
endif

ifeq($(BUILD_TYPE), WIN32)
  SRC_DIRS += AllegroRenderer
endif

EXCLUDE_SRC_FILES = Actors/ObsoleteActor.c

SRC_FILES = \
  $(filter-out \
    $(EXCLUDE_SRC_FILES) \
    $(foreach dir, $(SRC_DIRS), $(wildcard $(dir)/*.c)))

#113450 - tepples - Wed Dec 27, 2006 9:44 pm

gmiller wrote:
I have #ifdef's for platform specific code in files. I understand that this is a trade off but I have some files where I have platform specific forms of a particular function and I like all of the variants in the same file for ease of porting.

Unless you, say, want to use a Vorbis stream on one platform and tracked music on another platform with less storage and less CPU. And are you really a bad enough dude to abstract over the difference between a frame buffer based graphics engine on Allegro and a tile/sprite based graphics engine on GBA with conditionals alone unless you're conditioning out a whole file?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#113454 - sajiimori - Wed Dec 27, 2006 10:38 pm

Oh man, I'm gonna use that next time I'm in a technical discussion.

"Sure, but are you a bad enough dude to rewrite this algorithm using manual recursion and optimizing out loop invariants, while tripling the length of the code??"

:D

#113472 - sgeos - Thu Dec 28, 2006 1:23 am

tepples wrote:
unless you're conditioning out a whole file?

Thats how you do it. You'd probably need to conditionally convert your resources as well. Makefile level stuff.

sajiimori wrote:
Oh man, I'm gonna use that next time I'm in a technical discussion.

tepples wrote:
are you really a bad enough dude to...

lol

-Brendan

#113479 - poslundc - Thu Dec 28, 2006 3:29 am

Another argument against using automagic wildcard in your makefiles: when working in team environments it means you can't check new files into source control until you are confident they are building and linking correctly.

Depending on what type of RCS you're using, forgetting to check new files in is often one of the bigger causes of breaks, which is why I try to add new files to the repository when I create them... of course, this wouldn't work with wildcard building (since I usually create new files off of duplicates of old files).

That said, wildcards can still be useful... we use them with our art assets, for example, which so far haven't required customized exclusion.

Dan.

#113480 - sajiimori - Thu Dec 28, 2006 4:11 am

On VSS, I checked in empty files as soon as I created them. Compiling an empty .cpp file doesn't hurt.

On Perforce, file checkins are part of a changelist, so the file isn't really added until you submit the changelist.

I see your downside as an upside, actually -- I'd prefer not to have broken code in the database.

#113482 - tepples - Thu Dec 28, 2006 5:03 am

poslundc wrote:
That said, wildcards can still be useful... we use them with our art assets, for example, which so far haven't required customized exclusion.

Until someone complains to the ESRB about something you removed from the game but forgot to remove from the build folder.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#113487 - poslundc - Thu Dec 28, 2006 5:14 am

tepples wrote:
poslundc wrote:
That said, wildcards can still be useful... we use them with our art assets, for example, which so far haven't required customized exclusion.

Until someone complains to the ESRB about something you removed from the game but forgot to remove from the build folder.


In fairness, I never knew that was in the build folder and I didn't expect it would build error-free anyway.

Dan.

#113489 - poslundc - Thu Dec 28, 2006 5:20 am

sajiimori wrote:
On VSS, I checked in empty files as soon as I created them. Compiling an empty .cpp file doesn't hurt.


That's fine if you want to start with an empty .cpp/h file. I very often want to modify an existing pair, though, and it's more convenient to copy the existing files, in which case they can't be added to the repository if they will build by doing so.

Quote:
On Perforce, file checkins are part of a changelist, so the file isn't really added until you submit the changelist.


Sounds nice. :(

Quote:
I see your downside as an upside, actually -- I'd prefer not to have broken code in the database.


It's hard to consider it "broken" if it's not even building. I'd rather not have people breaking the build by forgetting to check in new files... two sides of the same coin, really.

Dan.

#113620 - wintermute - Fri Dec 29, 2006 6:36 am

gmiller wrote:
Depending on what you do in your make file you can set on up to auto-magicly adjust to new files. I have mine set up to look for all of the source files (.c, .s, .cpp) in the source directory and build dependencies and them compile. The default is arm mode and using the appropriate compilers/assembler in thumb mode. If the file is .arm.c, .arm.cpp, .arm.s them the code will be in ARM mode instead of Thumb mode. This makes adding new files just dropping them into the correct folder and then type "make". I does mean that if you leave a file in the folder then you might link in extra but it works pretty good. This is not a method that I have seen many people use but it works for me.


A lot more people are using this method due to the template projects I provide with devkitARM. Despite the apparent complexity of the makefile it's probably the best approach for beginners unfamiliar with make.

I even use these templates for cross platform projects including different base rules and folders depending on the target platform.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#113658 - gmiller - Fri Dec 29, 2006 2:48 pm

I do use complex makefiles for some of my projects but in my class that I teach on RISC processors I have the students use the makefiles I describe because they don't have alot of experience with makefiles and there is little time to pick it up (8 classes, 8 hours each over 4 weeks).

#113697 - sajiimori - Fri Dec 29, 2006 9:23 pm

Quote:
I very often want to modify an existing pair, though, and it's more convenient to copy the existing files, in which case they can't be added to the repository if they will build by doing so.
I actually tend to discourage copy & pasting code in general, but putting #if 0 around the .cpp file is a 10-second way to solve this problem.

I've never had occasion to do that though, for the simple reason that I've never wanted to duplicate an entire module.