Split from: [TUT] Modularizing C Code: Managing large projects

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I created a main file, and included FileA.h and FileB.h, FileA.h includes FileB.h and calls some of it's functions, with further development, FileB.h includes FileA.h and attempts to call a function in FileA.h, but i get the message '###' was not declared in this scope

 

the files are like above, no classes, the definitions of each file are the first two and last lines of each file!, how do I solve the "not declared in this scope"?

thanks

 

Last Edited: Sat. Apr 22, 2017 - 12:19 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I hope you don't have any executable code in your '. h' files.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

If you are talking about circular references then create a third header that documents the core functions then have A and B include C but not each other. 

 

But it might help if you actually make up an example of what you are talking about to document the issue you have. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You both solved it!, I had faith that if i explained it someone would know what the issue was!. As I am fairly new to gcc(but experienced in some other program languages) I am moving quickly, and thus hitting complex issues, I saw a program a little while ago, and thought the ".h" files were the "module" files as in perl/java, but clearly not quite so!, I changed my files to .cpp, and split my serial file from being in/out to serial-out and serial-in. This worked as each file when initiated from the main file called out to state they had started, and, then, might call latter to pass out errors!. The serial-in handles commands to the chip and passes to the relevant file, but, being disconnected from the "out" thus does not create a circular reference!. This is a fundamental part of GCC and should probably be "stickied".

The only down side is that I had to move the port manipulation and interupt into the main file, would have liked to keep it in the serial files!.

thanks

Andrew

Last Edited: Sat. Apr 22, 2017 - 02:30 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Theone6000 wrote:
thought the ".h" files were the "module" files as in perl/java, but clearly not quite so!

No, .h files are merely plain text files pulled into the compilation unit (the source .c file) by the #include directive as a first step of compilation. What the "compiler proper" sees is the combined results of the .c files and the .h files #included.

 

To bring some light onto differences between C/C++ and onther "more modern" programming languages, consider this example:

 

You have a file main.c, and also some utility functions in util.c. The things from the latter that should be seen in main.c has declarations - extern declarations, to be precise - in the file util.h. Those extern declarations are "function prototypes, or "headers" (thus the name "header file". Here's an example:

 

int someUtilFunction(char p);

For functions the "extern" is implied and need not be explicitly stated.

 

In main.c you have

#include "util.h""

The net effect is that the prototype is seen when compiling main.c. For the compiler proper there is no difference between this, and if you actually had the prototype itself in the main.c file. There are two things handy with having the prototype in a separate file:

 

1) Other users of the utilities can just #include the header file, rather thtan explicitly having the headers in their source file(s).

 

2) The header file can be #include'd in util.c. The point with doing this is that you now have a way to make sure that the actual implementation of the function in util.c adheres to the prototype in util.h, and that the exact same prototype is used when compiling main.c. Thus, you have a binding contract between main.c and util.c, not only about the name of the function but also about the parameters and the return value.

 

Also note another difference between some other languages and C: Merely #include'ing util.h in main.c and compiling the latter does not in any way imply that util.c will be compiled. You have to explicitly compile util.c as a a separate step. (The results of those two compilations will then be combined into an executable by the linker, but that's another story). A term often used for this scheme is "separate compilation.

 

The naming of util.c and util.h is merely a convention (but a very good one, indeed!). There is no rule saying that a source file and its header file must have the same base name (but again, it is a very good convention to adhere to!). From this you will deduce that, in general, there is no way for a C compiler to know that main.c is dependent upon util.c just based on the fact that main.c #include's util.h. (I could just as well rename util.c to eggman.c and rename util.h to walrus.h, (and fix the #include in main.c) and the C compiler would not protest at all. (Apart from the joy of having inserted a reference to a great pop song into your project, this would be very stupid to do since it would just confuse the human reader, but the compiler knows nothing of pop... :-) )

 

For many Java and C# coders coming to C/C++, the above is a somewhat startling revelation. If your eyebrows went up a bit then you are not alone. But every C/C++ programmer needs to understand this basic fact about how most all C/C++ compilers work, and what the semantics of the #include directive are.

 

HTH!

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hope you include guard statements at beginning (and end) of each. 

 

#ifndef FILEA_H
#define FILEA_H
....
#endif 

Prevents accidental multiple inclusion of header files.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net