Author Topic: [GCC] how deep is too deep  (Read 8816 times)

0 Members and 1 Guest are viewing this topic.

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
[GCC] how deep is too deep
« on: July 13, 2018, 08:01:18 pm »
I am trying to write a modular program but I now keep getting told that header files are too deeply nested. I have a projects variable header file, this calls an atmega.h files that lists everything I am using. how many levels down am i allowed to go by this cryptic compiler?
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [GCC] how deep is too deep
« Reply #1 on: July 13, 2018, 08:04:18 pm »
See if there's another atmega.h on your system (as that's a common name and it's possible that you've inadvertently caused an infinite loop of inclusion).

Alternately, rename your "atmega.h" to "atmega_target.h" or "myatmega.h" or "projatmega.h" or something and see if that makes the error go away.
 

Offline dmills

  • Super Contributor
  • ***
  • Posts: 2093
  • Country: gb
Re: [GCC] how deep is too deep
« Reply #2 on: July 13, 2018, 08:11:17 pm »
Plenty!
Methinks someone forgot some include guards...

foo.h
Code: [Select]
#ifndef FOO_INCL
#define FOO_INCL

#include "bar.h"

#endif

bar.h
Code: [Select]
#ifndef BAR_INCL
#define BAR_INCL

#include"foo.h"

#endif

main.c
Code: [Select]
#include "foo.h"

Now the first time foo.h is included in main the contents are brought in because FOO_INCL is not defined, and FOO_INCL becomes defined, foo.h then includes bar.h which when in tern includes foo.h..... But FOO_INCL is now defined so the include of foo.h evaluates to empty stopping the recursion. 

These loops can be much deeper then this if you are not paying attention.
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2905
  • Country: gb
Re: [GCC] how deep is too deep
« Reply #3 on: July 13, 2018, 08:19:16 pm »
Agree - you have recursive inclusion - I don't know the exact limit for gcc but it is deep enough that you should not be running into it.

The compiler has several flags which control the directories searched for include files - plus remember including with "" uses a different path to files included with <>
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [GCC] how deep is too deep
« Reply #4 on: July 13, 2018, 08:35:25 pm »
Oh, i have the compiler suddenly failing to find a local header file that points to atmega_user.h yet no issues with not having all of the other included files listed in it. A complete contradiction.
 

Offline ajb

  • Super Contributor
  • ***
  • Posts: 2596
  • Country: us
Re: [GCC] how deep is too deep
« Reply #5 on: July 13, 2018, 08:49:17 pm »
You might still have a circular inclusion problem.  When you have interdependent code modules you need to be careful about how you structure your files so that each piece can see all of its dependencies without creating circular dependencies.  As a general rule, try to keep includes in .c files instead of in .h files as much as possible, and only include what each file actually needs.  This will reduce the complexity of your dependency tree and speed up builds, as unnecessary includes will cause unnecessary rebuilding of files when the included files change. 

It sounds like maybe you're using atmega.h as a way of getting a bunch of dependencies down to a single file you can include in most of your other files, is that right?  That's certainly tempting as it seems like it makes managing your dependencies through a complex project easier, but overconsolidation leads to headaches as you've discovered. 
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [GCC] how deep is too deep
« Reply #6 on: July 13, 2018, 08:52:09 pm »
Plenty!
Methinks someone forgot some include guards...

foo.h
Code: [Select]
#ifndef FOO_INCL
#define FOO_INCL

#include "bar.h"

#endif

bar.h
Code: [Select]
#ifndef BAR_INCL
#define BAR_INCL

#include"foo.h"

#endif

main.c
Code: [Select]
#include "foo.h"

Now the first time foo.h is included in main the contents are brought in because FOO_INCL is not defined, and FOO_INCL becomes defined, foo.h then includes bar.h which when in tern includes foo.h..... But FOO_INCL is now defined so the include of foo.h evaluates to empty stopping the recursion. 

These loops can be much deeper then this if you are not paying attention.


That will not entirely solve it as standard AVR GCC headers files are too deeply nested and what you are saying involves doing this to the file itself not the file calling it. Anyone got a (soft) wall I can bang my head on?
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [GCC] how deep is too deep
« Reply #7 on: July 13, 2018, 08:55:00 pm »
It sounds like maybe you're using atmega.h as a way of getting a bunch of dependencies down to a single file you can include in most of your other files, is that right?  That's certainly tempting as it seems like it makes managing your dependencies through a complex project easier, but overconsolidation leads to headaches as you've discovered. 

This is precisely the problem I guess. i was trying to solve "another" problem of every time I make a new file it has a ton of stuff that needs including for me to discover one missing file at a time. I'll go back and change it.
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [GCC] how deep is too deep
« Reply #8 on: July 13, 2018, 08:57:01 pm »
That will not entirely solve it as standard AVR GCC headers files are too deeply nested and what you are saying involves doing this to the file itself not the file calling it. Anyone got a (soft) wall I can bang my head on?
The chance that you're hitting the exact limit on a non-infinite chain of include files on your (maybe very first) project is vanishingly low.

I've been using GCC on and off for almost 30 years now across a dozen targets and I've literally never hit this limit without an infinite loop of includes.
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [GCC] how deep is too deep
« Reply #9 on: July 13, 2018, 09:00:41 pm »
The C standard requires support for at least 15 deep include files, and the gcc limit seems to be 200.

From the GCC Preprocessor manual, section 11.2
Quote
Nesting levels of ‘#include’ files.
We impose an arbitrary limit of 200 levels, to avoid runaway recursion. The standard requires at least 15 levels.
 

Offline MosherIV

  • Super Contributor
  • ***
  • Posts: 1530
  • Country: gb
Re: [GCC] how deep is too deep
« Reply #10 on: July 13, 2018, 10:08:06 pm »
Personally, I think it is a bad idea to do #include in header files.
It means it is difficult (impossible) to manage dependancies.
Personally, I think it is done because many coders cannot be bothered to look after coupling and dependancies, rather they prefer the ease (lazyness) of not having to type out the #includes in source files.

I have managed to develop an entire c++ based product without a single #include in header files.
(No it was not "hello world")

(Let the debate/flaming begin  :box: )
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [GCC] how deep is too deep
« Reply #11 on: July 13, 2018, 10:12:32 pm »
Not even cstdint? Not including that would preclude writing functions with return types of uint16_t, etc.

On that basis alone, I disagree. I believe that a header file should #include any other header files it needs such that it can be standalone included by a .c/.cpp file.
« Last Edit: July 13, 2018, 10:15:24 pm by sokoloff »
 

Offline Sal Ammoniac

  • Super Contributor
  • ***
  • Posts: 1668
  • Country: us
Re: [GCC] how deep is too deep
« Reply #12 on: July 13, 2018, 10:54:39 pm »
Plenty!
Methinks someone forgot some include guards...

foo.h
Code: [Select]
#ifndef FOO_INCL
#define FOO_INCL

#include "bar.h"

#endif

bar.h
Code: [Select]
#ifndef BAR_INCL
#define BAR_INCL

#include"foo.h"

#endif

main.c
Code: [Select]
#include "foo.h"

Now the first time foo.h is included in main the contents are brought in because FOO_INCL is not defined, and FOO_INCL becomes defined, foo.h then includes bar.h which when in tern includes foo.h..... But FOO_INCL is now defined so the include of foo.h evaluates to empty stopping the recursion. 

These loops can be much deeper then this if you are not paying attention.


If your compiler supports it (and most do), "#pragma once" is a cleaner solution. Put that at the top of your header files and that's all you need--that one line.
Complexity is the number-one enemy of high-quality code.
 
The following users thanked this post: andyturk, elgonzo, radar_macgyver

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: [GCC] how deep is too deep
« Reply #13 on: July 14, 2018, 12:18:01 am »
Personally, I think it is a bad idea to do #include in header files.
It means it is difficult (impossible) to manage dependancies.
Do you mean build system dependencies? I.e., where a change to foo.h means you have to re-compile a bunch of implementation files?

If so, that's handled easily (with GCC and make) via the -MD command line option.
 

Offline dmills

  • Super Contributor
  • ***
  • Posts: 2093
  • Country: gb
Re: [GCC] how deep is too deep
« Reply #14 on: July 14, 2018, 12:56:10 am »
Anything following #pragma is by definition implementation defined, which is fine if you know you will only ever be targeting one known toolchain but IMHO the advantage in this case is so minimal as to make it not worth it.

Regards, Dan.
 
The following users thanked this post: jancumps

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: [GCC] how deep is too deep
« Reply #15 on: July 14, 2018, 01:08:38 am »
Anything following #pragma is by definition implementation defined, which is fine if you know you will only ever be targeting one known toolchain but IMHO the advantage in this case is so minimal as to make it not worth it.

Regards, Dan.

Do you work on Cray?
 

Offline ajb

  • Super Contributor
  • ***
  • Posts: 2596
  • Country: us
Re: [GCC] how deep is too deep
« Reply #16 on: July 14, 2018, 02:47:36 am »
Personally, I think it is a bad idea to do #include in header files.
It means it is difficult (impossible) to manage dependancies.

Includes in headers should definitely be limited, but providing access to data type definitions (like stdint, but also custom types used in libraries or whatever) and compile-time configuration values are two important occasions where it makes sense. 
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11620
  • Country: my
  • reassessing directives...
Re: [GCC] how deep is too deep
« Reply #17 on: July 14, 2018, 03:43:28 am »
i'm not a fan of #pragma myself. i'm not into a risk of changing them all in my many h files back into classic guard code when i move to different IDE long time after that doesnt support the pragma. there are simple rules to be used to avoid the drawbacks but "widely supported" argument is not good enough for me. ymmv.

I have managed to develop an entire c++ based product without a single #include in header files.
you must be a typing fan of many #include in source files. i have h files just to collect 5 - 10 #include in it because i hate to type 5 - 10 #include every time i create a c file. ymmv.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: [GCC] how deep is too deep
« Reply #18 on: July 14, 2018, 04:22:38 am »
Quote
Personally, I think it is a bad idea to do #include in header files.
It's a common "requirement" that head files be "self-contained", which means that they should #include the files necessary to satisfy any symbols that they use.  Being able to use uint8_t and the like is an obvious example.  But if you have tcp.h that references symbols defined in ip.h to get at the pseudo-header, then tcp.h should include ip.h

Quote
It means it is difficult (impossible) to manage dependancies.
dependencies are easily managed by software.   That's what the "make depend" step is for.
I agree with everyone who says that it's extremely unlikely that you're hitting "maximum depth" via anything other than a loop of some kind.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [GCC] how deep is too deep
« Reply #19 on: July 14, 2018, 06:57:33 am »
Well the circular problem is gone. I have my #include "project_variables.h" that is not finding the file, I put it in the same folder as main.c

Where do i declare external variables? can that go in a header file?
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11620
  • Country: my
  • reassessing directives...
Re: [GCC] how deep is too deep
« Reply #20 on: July 14, 2018, 07:08:27 am »
declaring external variables in h will make it visible to any c that includes the h its a common method for beginner or variables which are really "global", it may break encapsulation rule it may not depending on the complexity. it may difficult to search in the hierarchy from which source its originating, who have right and control over it and what its logical purpose. external variables can be declared as well at the beginning of each c relating to it, but ymmv.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [GCC] how deep is too deep
« Reply #21 on: July 14, 2018, 07:25:46 am »
Hold on, how can I declare the variable multiple times? My variables will be global as for example the ADC interrupt routine needs to put data into variables that will be retained after it exits. I have a timer variable going that will keep track of time that everything needs access to
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: [GCC] how deep is too deep
« Reply #22 on: July 14, 2018, 07:43:56 am »
You can and should DECLARE externals in a header file but you should *never* DEFINE them in a header.  They can have multiple declarations, so they are visible in all the C files that need them, but *MUST* only be defined in a single place, so in *ONE* C file.

Rule of thumb:  If it allocates or initialises storage, (whether that be RAM or program memory or any other type of memory including MCU 'fuse' bits) it goes in a C file, not a header.  Note that device specific headers that map variables to hardware registers don't allocate storage as the registers already exist at fixed addresses.

See http://www.gamedev.net/page/resources/_/technical/general-programming/organizing-code-files-in-c-and-c-r1798 (there's a newer version of that document but its more MS/PC centric so less useful to embedded or GCC programmers).
« Last Edit: July 14, 2018, 08:12:05 am by Ian.M »
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [GCC] how deep is too deep
« Reply #23 on: July 14, 2018, 07:53:30 am »
Ah so my thinking was right to have a global variables *.c and *.h file.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26878
  • Country: nl
    • NCT Developments
Re: [GCC] how deep is too deep
« Reply #24 on: July 14, 2018, 08:17:19 am »
Personally, I think it is a bad idea to do #include in header files.
It means it is difficult (impossible) to manage dependancies.
Personally, I think it is done because many coders cannot be bothered to look after coupling and dependancies, rather they prefer the ease (lazyness) of not having to type out the #includes in source files.

I have managed to develop an entire c++ based product without a single #include in header files.
(No it was not "hello world")

(Let the debate/flaming begin  :box: )
But the problem with that is that you have to add an include to each and every file which needs it and dependancies are less clear. The latter makes it harder for someone else to work on the project. It is not hard to spend a couple of hours on figuring out which include should be included where (hence the existence of this thread).

I have a strict policy to have one include file which includes all other includes in the right order. This gets rid of the 'include hell' which quickly emerges when working on a larger project.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 
The following users thanked this post: donotdespisethesnake


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf