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

0 Members and 1 Guest are viewing this topic.

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11650
  • Country: my
  • reassessing directives...
Re: [GCC] how deep is too deep
« Reply #25 on: July 14, 2018, 08:47:30 am »
you "define" variable in c where its most related. for example adc_read.c along with other related adc functions (read write etc). to make it accessible to outsiders, you "declare" them (including functions) in adc_read.h so anything using adc service will #include adc_read.h thats how logically we group things. but sometime a variable is not that too specific to a particular subject, it may related (equally) to several unit (c files) but not all units, so borderline can be obscured and it will be entirely up to you where to put (define) it, 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 andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: [GCC] how deep is too deep
« Reply #26 on: July 14, 2018, 11:34:35 am »
dependencies are easily managed by software.   That's what the "make depend" step is for.
The problem is that it's easy to end up with false dependencies, especially if you don't separate function and type declarations. I'm sure most have experienced situations where touching a header file forces completely unrelated source files to be rebuilt.

Offline MosherIV

  • Super Contributor
  • ***
  • Posts: 1530
  • Country: gb
Re: [GCC] how deep is too deep
« Reply #27 on: July 14, 2018, 01:30:17 pm »
Quote
Not even cstdint? Not including that would preclude writing functions with return types of uint16_t, etc.
Quote
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.
This is the starting point to say that it is OK to allow #include in header files.

Quote
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?
Sort of. Yes it is to do with build dependencies but dependencies are related to module coupling. You want low coupling.

Quote
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.
This is a complete miss-understanding of the 'coupling principle'. Achieving low coupling is not the same as saying that a module must be 'stand alone'.
This is true for binary library modules BUT NOT in house software module being developed.

Quote
dependencies are easily managed by software.   That's what the "make depend" step is for.
Yet another excuse.
How often do developer actually check the dependency tree?
How do developers know when a problem is starting when looking at the results of software to map the dependencies?

Quote
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.
Actually the dependencies are absolutely clear.
By ONLY using includes in source files, the list of includes in the source file MUST be correct or it will not compile.
Therefore the list of #includes in a source file IS the list of dependent headers (assuming unnecessary includes have been removed).
It is now easy to always know what the dependencies are just by looking at the list.
You do not need to run tools to work out what the dependency is.
Let face it how often do developer actually look at the dependencies - this way they are always looking at it.

Quote
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.
Quote
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.
This may sound like the solution but it actually increases coupling. See the next quote and response :
By having a single file with all the includes, everything is now dependent  :palm:

Quote
The problem is that it's easy to end up with false dependencies, especially if you don't separate function and type declarations. I'm sure most have experienced situations where touching a header file forces completely unrelated source files to be rebuilt.
This is exactly one of the problems that having #include in header files cause!



By allowing #include in header files, it is inevitable that you end up with the high coupling diagram.
Dissallowing #include in header files cannot stop the high coupling problem but it will force developers to look and think about it all the time.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26907
  • Country: nl
    • NCT Developments
Re: [GCC] how deep is too deep
« Reply #28 on: July 14, 2018, 02:04:03 pm »
By allowing #include in header files, it is inevitable that you end up with the high coupling diagram.
Dissallowing #include in header files cannot stop the high coupling problem but it will force developers to look and think about it all the time.
The latter is exactly why this approach wastes time (friggin' huge amounts!) and the root cause is lack of documentation. Having one include to include all other includes is a far better way because this also shows the dependancies immediately AND there are no circular dependancies. It also makes it easy to extend software. You only need to include one include file and add new include files in one place. I agree that excessive nesting of include files is bad but sometimes it is necessary. For example when you want to use a library. These usually have an include file which forms an API and depending on the OS, compiler, target, etc  other include files get included. You can't avoid a high level of coupling within a single program anyway.

I've seen lots of examples where programmers painted themselves into a corner due to include file cross dependancies which are easely avoided by having all include file being included in a single include file.
« Last Edit: July 14, 2018, 02:23:10 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 
The following users thanked this post: hans

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [GCC] how deep is too deep
« Reply #29 on: July 14, 2018, 02:14:11 pm »
I favor the “to use this include file, you may freely include only it without compile errors” approach.
Having to include cstdint before another include file is a pointless waste of time, IMO.

I’ve worked on projects where you include “kitchen_sink.h” and didn’t especially like that on large projects. For a typical uC project, that’s fine.

For me, it’s about what wastes the least dev time and takes the least dev braincycles to work in. For me, that’s standalone includes, but not necessarily full-project includes.
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: [GCC] how deep is too deep
« Reply #30 on: July 14, 2018, 02:42:20 pm »
How often do developer actually check the dependency tree?
How do developers know when a problem is starting when looking at the results of software to map the dependencies?
I never check build system dependencies (any more) because the compiler generates perfect dependency info each time it produces an object file. This is a GCC specific feature though. (And a good reason to use GCC!)

Quote
By ONLY using includes in source files, the list of includes in the source file MUST be correct or it will not compile.
The same statement is true when includes are nested. I.e., "include correctness" doesn't uniquely support your position.

Quote
Therefore the list of #includes in a source file IS the list of dependent headers (assuming unnecessary includes have been removed).
It is now easy to always know what the dependencies are just by looking at the list.
You do not need to run tools to work out what the dependency is.
Let face it how often do developer actually look at the dependencies - this way they are always looking at it.
Why do you want developers looking at include dependencies? That seems like wasted effort--something that should be done by the IDE or build system.

Quote
Dissallowing #include in header files cannot stop the high coupling problem but it will force developers to look and think about it all the time.
Disallowing nested includes makes refactoring more difficult because the same information gets repeated in multiple places. I.e., if I need to use a "module" that depends on 5 others, I have to put those 5 includes directly in my implementation. Fine. But when the guy who maintains that module changes his internal dependencies, your rule says my code has to change too. That's bad.

I bet it leads to developers on your team re-implementing stuff privately specifically so they don't have to deal with this guideline. That's even worse.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: [GCC] how deep is too deep
« Reply #31 on: July 14, 2018, 03:15:45 pm »
Ah so my thinking was right to have a global variables *.c and *.h file.

I'm not much on global variables.  Ownership is a problem, contamination is a possible result.  I would rather place the ADC value in a managed container like a queue where the queue structure belongs to, and is only visible by, the queue handler.

ADC -> Queue -> Application

No global variables!

I don't have such heartburn over file static variables where the variable is only visible to functions in the same .c file.  Clearly, the queue structure and head/tail pointers would be file static variables.

It might be tempting to define the queue data structure and the queue size along with the head and tail pointers in queue.h.  But that allows other files to include queue.h and gain some knowledge about how the queue is implemented. What possible good can come from that?  Better, in my view, to define everything related to the queue implementation inside queue.c.  The only thing exposed in queue.h is the names and parameters (data types) for the insert and remove functions.

If a function doesn't have a 'need to know', it shouldn't automatically get a 'right to know'.

Keep stuff local and keep it containted!

 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: [GCC] how deep is too deep
« Reply #32 on: July 14, 2018, 03:17:43 pm »
Disallowing nested includes makes refactoring more difficult because the same information gets repeated in multiple places. I.e., if I need to use a "module" that depends on 5 others, I have to put those 5 includes directly in my implementation. Fine. But when the guy who maintains that module changes his internal dependencies, your rule says my code has to change too. That's bad.
If that happens, then either the module has no separation between public and private interfaces, which is bad, or you've bypassed the interface and are directly poking around in the internals, which is also bad.

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: [GCC] how deep is too deep
« Reply #33 on: July 14, 2018, 03:42:52 pm »
Just for fun, here's one of the GCC-generated dependency rules (for a Makefile) for one file. The build system produces one of these rules for every .c or .cc file in the entire project automatically.

Code: [Select]
build/debug_obj/main.o: main.cc \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/nrf52/timer.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/error.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/cstdint \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard/bits/c++config.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard/bits/os_defines.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard/bits/cpu_defines.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/lib/gcc/arm-none-eabi/6.3.1/include/stdint.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/stdint.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/machine/_default_types.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/features.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/_newlib_version.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/_intsup.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/_stdint.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/nrf52/peripheral.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/nrf52/mcu_device.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/device/nrf52840.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/rtx5/include/core_cm4.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/rtx5/include/cmsis_version.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/rtx5/include/cmsis_compiler.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/rtx5/include/cmsis_gcc.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/rtx5/include/mpu_armv7.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/toolchain/system_nrf52840.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/device/nrf52840_bitfields.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/device/nrf52840_peripherals.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/functional \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/stl_function.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/move.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/concept_check.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/type_traits \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/backward/binders.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/typeinfo \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/exception \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/atomic_lockfree_defines.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/exception_ptr.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/exception_defines.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/nested_exception.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/hash_bytes.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/new \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/tuple \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/utility \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/stl_relops.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/stl_pair.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/initializer_list \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/array \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/stdexcept \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/string \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/stringfwd.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/memoryfwd.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/char_traits.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/stl_algobase.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/functexcept.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/cpp_type_traits.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/ext/type_traits.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/ext/numeric_traits.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/stl_iterator_base_types.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/stl_iterator_base_funcs.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/debug/assertions.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/stl_iterator.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/ptr_traits.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/debug/debug.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/predefined_ops.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/postypes.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/cwchar \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/wchar.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/_ansi.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/newlib.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/config.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/machine/ieeefp.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/reent.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/lib/gcc/arm-none-eabi/6.3.1/include/stddef.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/_types.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/machine/_types.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/lock.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/cdefs.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/lib/gcc/arm-none-eabi/6.3.1/include/stdarg.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/_locale.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/allocator.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard/bits/c++allocator.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/ext/new_allocator.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/localefwd.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard/bits/c++locale.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/clocale \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/locale.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/_ansi.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/iosfwd \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/cctype \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/ctype.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/ostream_insert.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/cxxabi_forced.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/range_access.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/basic_string.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/ext/atomicity.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard/bits/gthr.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard/bits/gthr-default.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/arm-none-eabi/thumb/v7e-m/fpv4-sp/hard/bits/atomic_word.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/ext/alloc_traits.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/alloc_traits.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/ext/string_conversions.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/cstdlib \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/stdlib.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/machine/stdlib.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/alloca.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/cstdio \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/stdio.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/types.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/machine/endian.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/machine/_endian.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/select.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/_sigset.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/_timeval.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/timespec.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/_timespec.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/_pthreadtypes.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/machine/types.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/stdio.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/cerrno \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/errno.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/errno.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/functional_hash.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/basic_string.tcc \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/bits/uses_allocator.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/nrf52/soft_device.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/nrf52/error.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/nrf52/advertisement.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/ble_gap.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/ble_types.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/ble_ranges.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/nrf_svc.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/flipbuffer.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/cassert \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/assert.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/cstring \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/string.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/sys/string.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/common/nrf_sdh_ble.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/libraries/util/app_util.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/lib/gcc/arm-none-eabi/6.3.1/include/stdbool.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/device/compiler_abstraction.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/libraries/util/nordic_common.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/device/nrf.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/device/nrf52840.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/device/nrf52840_bitfields.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/device/nrf51_to_nrf52840.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/device/nrf52_to_nrf52840.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/device/compiler_abstraction.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/ble.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/ble_gap.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/ble_l2cap.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/ble_err.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/nrf_error.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/ble_gatt.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/ble_gattc.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/ble_gatts.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/libraries/experimental_section_vars/nrf_section_iter.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/libraries/experimental_section_vars/nrf_section.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/libraries/util/nordic_common.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/libraries/util/nrf_assert.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/libraries/util/app_error.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/libraries/util/sdk_errors.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/nrf_error.h \
 sdk_config.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/libraries/util/app_error_weak.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/libraries/util/sdk_errors.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/nrf_sdm.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/nrf_soc.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/nrf_error_soc.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/softdevice/s132/headers/nrf_error_sdm.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/rtx5/event.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/rtx5/kernel.h \
 RTX_Config.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/rtx5/include/cmsis_os2.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/rtx5/include/rtx_os.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/rtx5/include/cmsis_os2.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/rtx5/thread.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/segger/sysview.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/segger/SEGGER/SEGGER_SYSVIEW.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/segger/SEGGER/SEGGER.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/segger/Config/Global.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/panamint/the.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/boards/boards.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/drivers_nrf/hal/nrf_gpio.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/drivers_nrf/hal/nrf_peripherals.h \
 /usr/local/arm/gcc-arm-none-eabi-6-2017-q1-update/arm-none-eabi/include/c++/6.3.1/stdlib.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/boards/pca10056.h \
 /Volumes/Users/andy/code/ARM/reproducer_363/nordic_sdk_14/components/drivers_nrf/delay/nrf_delay.h


There may be 100+ such files generated. They're all incorporated into the build with a single line at the bottom of the Makefile:

Code: [Select]
-include $(OBJECTS:%.o=%.d)

 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26907
  • Country: nl
    • NCT Developments
Re: [GCC] how deep is too deep
« Reply #34 on: July 14, 2018, 03:44:08 pm »
Dissallowing #include in header files cannot stop the high coupling problem but it will force developers to look and think about it all the time.
Disallowing nested includes makes refactoring more difficult because the same information gets repeated in multiple places. I.e., if I need to use a "module" that depends on 5 others, I have to put those 5 includes directly in my implementation. Fine. But when the guy who maintains that module changes his internal dependencies, your rule says my code has to change too. That's bad.

I bet it leads to developers on your team re-implementing stuff privately specifically so they don't have to deal with this guideline. That's even worse.
I know it leads to developers creating their own private version. I've seen it happen!
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11650
  • Country: my
  • reassessing directives...
Re: [GCC] how deep is too deep
« Reply #35 on: July 14, 2018, 03:57:37 pm »
Quote
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.
Quote
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.
This may sound like the solution but it actually increases coupling.
coupling is dependency, dependency is coupling yes we know that. but i dont have problem coupling (in anyway if necessary) my code with the code high above, such as standard library, or ready made library made by others that we consider complete and a blackbox. your diagram is correct, and i agree with the idea of low coupling (dependency) if we are building our own reusable library. but have you experienced having to type standard library #includes in sources of your particular application? like...
Quote
#include <stdlib.h>
#include <stdlio.h>
#include <math.h>
etc etc
i'm guessing you are a fan of those...

looking at your diagram, the structure on the right is ideal because all arrows are heading downward, but some application we cant achieve that unless we combine 2 or more small units into one bigger unit, but they are different purposes or "separable" logically so it will not be ideal to combine them frm that point of view. the other way is to rearrange the diagram so they are on the same level, like a library i did sometime ago (see attached). the green boxed are closely/heavily/highly coupled, i cannot move one of them to the bottom or up without making the arrows pointing all down. red is c standard library as you can see they can be easily brought down because they are different "group". my application will simply call #include <extlib.h> and everything (including c std library required) will be ready on silver platter.
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 sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [GCC] how deep is too deep
« Reply #36 on: July 14, 2018, 04:36:35 pm »
Disallowing nested includes makes refactoring more difficult because the same information gets repeated in multiple places. I.e., if I need to use a "module" that depends on 5 others, I have to put those 5 includes directly in my implementation. Fine. But when the guy who maintains that module changes his internal dependencies, your rule says my code has to change too. That's bad.
If that happens, then either the module has no separation between public and private interfaces, which is bad, or you've bypassed the interface and are directly poking around in the internals, which is also bad.
Consider the case where a library author starts on AVR and gives you a function taking 2 ints and returning a long. On AVR, those are 16 and 32 bits. Now, they want to port to another platform and need to specify the size. Suddenly, all callers need to include cstdlib in order to include the library header? That’s a waste of time, IMO. Note that the code would likely still compile (albeit with warnings if you have strict warning settings) in the other case.

Now, a novice dev wants to use this library from GitHub. They aren’t going to know how to fix the missing include in all likelihood. Contrast with the case where the library header includes cstdlib on this change. What’s the worst case outcome? A compiler warning on implicit, lossless type conversion. Code still “works” and the warning is straightforward for anyone who is likely to be running with -Wall.
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1198
  • Country: fi
Re: [GCC] how deep is too deep
« Reply #37 on: July 14, 2018, 05:19:10 pm »
Consider the case where a library author starts on AVR and gives you a function taking 2 ints and returning a long. On AVR, those are 16 and 32 bits. Now, they want to port to another platform and need to specify the size. Suddenly, all callers need to include cstdlib in order to include the library header? That’s a waste of time, IMO. Note that the code would likely still compile (albeit with warnings if you have strict warning settings) in the other case.
I never said you should never include headers from other headers, so that's a strawman argument. Besides, standard library headers don't change, so they're not a problem anyway. But I have worked on enough projects where out of control dependencies were real workflow impediments. Not only through longer build times, but also making testing and code reuse harder. And even if the build time increases are very small on average, it'll soon dwarf the effort required to not have such enormous dependencies in the first place.

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [GCC] how deep is too deep
« Reply #38 on: July 14, 2018, 08:22:52 pm »
Consider the case where a library author starts on AVR and gives you a function taking 2 ints and returning a long. On AVR, those are 16 and 32 bits. Now, they want to port to another platform and need to specify the size. Suddenly, all callers need to include cstdlib in order to include the library header? That’s a waste of time, IMO. Note that the code would likely still compile (albeit with warnings if you have strict warning settings) in the other case.
I never said you should never include headers from other headers, so that's a strawman argument. Besides, standard library headers don't change, so they're not a problem anyway. But I have worked on enough projects where out of control dependencies were real workflow impediments. Not only through longer build times, but also making testing and code reuse harder. And even if the build time increases are very small on average, it'll soon dwarf the effort required to not have such enormous dependencies in the first place.
You’re right. It was MosherIV who made that argument. My apologies to you.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [GCC] how deep is too deep
« Reply #39 on: July 14, 2018, 08:25:16 pm »
Gee calm down people. I'm still looking at how I implement this, nothing I am writing would be used in parts but yes it should be as modular as possible.
 

Offline bson

  • Supporter
  • ****
  • Posts: 2270
  • Country: us
Re: [GCC] how deep is too deep
« Reply #40 on: July 14, 2018, 09:30:58 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?
Gcc simply adopts 256 as this is a common limit.  It may even have been adopted as a standard.  Same as MSVC etc.

It's just a sane limit to keep it from recursively including a header file indefinitely until it runs out of memory (which actually won't happen on x64 systems these days; they just fill your disk with page files and effectively never finish), and I can't imagine any SDK needs this.  That would be utterly ridiculous.
 

Online Doctorandus_P

  • Super Contributor
  • ***
  • Posts: 3362
  • Country: nl
Re: [GCC] how deep is too deep
« Reply #41 on: July 14, 2018, 09:48:01 pm »
I think the minimum required depth is 8 redirections, and the practical limit may be limited by the number of characters in the file names. those #include directives can have relative / absolute path names in them, and path names may be added by makefiles and such.

Here are some test results of a header file including itself and the results vary between 200 and 1024.
https://stackoverflow.com/questions/12125014/are-there-limits-to-how-deep-nesting-of-header-inclusion-can-go

So if this becomes a problem for you, it is very likely you have some circular reference in the header files. This is one of the reasons why there almost always is an include guard in every header file.
https://en.wikipedia.org/wiki/Include_guard

This is also an interesting and related read:
http://gernotklingler.com/blog/care-include-dependencies-cpp-keep-minimum/
« Last Edit: July 14, 2018, 09:52:37 pm by Doctorandus_P »
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [GCC] how deep is too deep
« Reply #42 on: July 14, 2018, 10:38:56 pm »
I think the minimum required depth is 8 redirections, and the practical limit may be limited by the number of characters in the file names. those #include directives can have relative / absolute path names in them, and path names may be added by makefiles and such.
Minimum number is set in section §5.2.4.1 of the language spec. It is 15.
I can’t see what this limit has to do with path name length in any way.
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1799
  • Country: us
Re: [GCC] how deep is too deep
« Reply #43 on: July 14, 2018, 10:40:59 pm »
Gcc simply adopts 256 as this is a common limit.  It may even have been adopted as a standard.  Same as MSVC etc.
Previously cited gcc docs in this thread, gcc has chosen 200 for this limit.
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: [GCC] how deep is too deep
« Reply #44 on: July 15, 2018, 01:57:17 pm »
This is also an interesting and related read:
http://gernotklingler.com/blog/care-include-dependencies-cpp-keep-minimum/
Good read, thanks! The blog mentions a program written at Google for maintaining the "Include what you Use" policy via tooling.

https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/WhyIWYU.md
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3240
  • Country: gb
Re: [GCC] how deep is too deep
« Reply #45 on: July 15, 2018, 03:05:24 pm »
Gee calm down people. I'm still looking at how I implement this, nothing I am writing would be used in parts but yes it should be as modular as possible.

If you want to make modular code then try to avoid global variables as much as possible.
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11650
  • Country: my
  • reassessing directives...
Re: [GCC] how deep is too deep
« Reply #46 on: July 15, 2018, 05:02:11 pm »
Gee calm down people. I'm still looking at how I implement this, nothing I am writing would be used in parts but yes it should be as modular as possible.
If you want to make modular code then try to avoid global variables as much as possible.
as much as this is ideal, its not achievable in practical application, small or big. he was talking about adc and timer value. its not going to be a good idea, to call hardware adc or timer function in each modular function.
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 Leiothrix

  • Regular Contributor
  • *
  • Posts: 104
  • Country: au
Re: [GCC] how deep is too deep
« Reply #47 on: July 15, 2018, 10:28:42 pm »
No, but you could have a simple inline getter function.

Then you can maintain some isolation and increase the flexibility of the ADC/timer module as well.

Sort of like a class...
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [GCC] how deep is too deep
« Reply #48 on: July 16, 2018, 07:53:40 am »
Right, next problem:

#include "project_variables.h"

No such file or directory. This is included in several files but I only get one instance of the error. Um it is either there or not! what is the compiler playing at. I have the file in the same folder as the main.c file.
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 12862
Re: [GCC] how deep is too deep
« Reply #49 on: July 16, 2018, 08:53:56 am »
Are *all* the files that include "project_variables.h" in the same folder as itself
 and "main.c"?
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf