0

I am working on a C project in which part of the code is generated by a different application. The separate files would contain the following:

  • Type definitions, main(), and other functions
  • Variable declarations (whose type definition is in the file above) and functions to work with those variables

As mentioned, the information in the second file is generated by a different program, but it uses the type declarations in the main file. Similarly, the main program uses the variables and functions defined in the second file.

I have tried using the "include" and "extern" statements but have not been very successful at it. Since the two files are getting information from each other, would it be more useful to break them up in three files as follows?

1) Type definitions

2) Variable declarations (using the types defined in file 1) and related functions

3) Main() and the rest of functions that use the two above files

If this was the way to go, how would it work? Would it use include or extern, and how would I need to use these clauses?

Any help you can provide is greatly appreciated. Thank you!

Irina
  • 1,333
  • 3
  • 17
  • 37
  • Welcome to Stack Overflow. Please read the [About] page soon. It sounds as though you need a header file to contain the type definitions that will be included by the code containing `main()` etc, and also by the generated code (by some more or less devious means). How much control do you have over what is generated? Does the generated code include any header you have control over? – Jonathan Leffler Aug 02 '13 at 22:09
  • Maybe an example of the two files and the type of the files should help you get the required solution here. – Uchia Itachi Aug 02 '13 at 22:10
  • Hi Jonathan, thank you for your reply. I have control over all code, including headers and the rest of the code in the generated file. I will get some relevant code from each of the files and post it. Thank you for the quick answer! – Irina Aug 02 '13 at 22:18

3 Answers3

1

There is nothing wrong with the layout you are suggesting. Perhaps some clarification on what extern and #include do would be helpful. 1) #include is a preprocessor directive which essentially says: `take the named file and pretend it is pasted in place of this directive'

2) extern is a C reserved word. Not to get into too many technicalities, but its meaning is: `the variable named in this statement is defined in a different place'. The space for a variable is reserved by the compiler exactly once, so if a function needs access to the variable in question, some information is needed before the definition is seen by the compiler. An extern declaration has enough information for the function to use the variable and the linker makes sure that a correct variable is used at a later stage.

So in your scenario, the file with type definitions will be #include'd in every file that refers to those types. If you want to collect all the variable definitions in one file, which will be compiled separately from other parts of your project, any file that uses those variables and will be compiled separately, needs to be supplied an extern declaration for each variable defined elsewhere. Note that if you simply include th file with variable definitions, the compiler will see the definition twice (first in the file with the definitions, then in the file that includes it) and assume you are trying to define each variable twice and will issue an error.

Finally, here is a simple scenario (it does not really make sense and is in bad style):

a.c---------

#include "t.h"

mytype a;
mytype b;

int f( int x, int y ) {

    return (x + y)*a - b;

}

m.c---------

#include <stdio.h> // for stdout
#include "t.h"
#include "v.h"

int main () {

    fprintf( stdout, "%d", a + b - f(1, 2) );

    return 0;

}

t.h-----------

typedef int mytype;

v.h-----------

#include "t.h"

extern mytype a, b;

int f( int, int );

v.h and t.h can be combined (it is a question of style and the project requirements). Note that a declaration of f in v.h has an implied extern in front of it.

alexsh
  • 1,121
  • 8
  • 12
  • Alex, that is fantastic information. I have separated my code as you mentioned and seem to have a problem. When I compile the two .c files, it tells me that I have undeclared variables in m.c - Basically, it's not seeing the variables I declared in a.c (even though I am compiling them using "gcc a.c m.c". What could I be doing wrong? I don't see any references to a.c in m.c above, so is m.c still supposed to be able to see the contents of a.c somehow? Thank you so much! – Irina Aug 04 '13 at 01:39
  • I have just tried that and it compiled just fine. Could you maybe post an error message gcc produces? Also try to compile them separately as in `gcc -c a.c` and `gcc -c m.c` and see what happens. Also, did you make sure that v.h and t.h are in the same directory? The variable information m.c needs comes from those header files. I changed one typo though: printf should have been fprintf – alexsh Aug 04 '13 at 21:51
0

As outlined in a comment, you will almost certainly need a header — call it header.h — which will be included in both the file containing the main program (file 1, call it main.c) and in the generated file (file 2, call it generated.c).

The header file will contain the type definitions and shared function declarations (and, perish the thought, declarations for any global variables). It will be self-contained and idempotent (see, amongst others, the Stack Overflow questions What are extern variables in C?, Should I use #include in headers?, How to link multiple implementation files in C?, and Linking against a static library).

Both main.c and generated.c will include header.h. To ensure that header.h is self-contained, one (or both) of the files will #include "header.h" as the first header.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0

Finally fixed. If anybody else has the same problem, I followed Alexsh's steps but I also had to include guards in my .h files to prevent redefinitions (otherwise it wouldn't compile). Thank you very much to both Alexsh and Jonathan for their help!

Irina
  • 1,333
  • 3
  • 17
  • 37