10

I have an ANSI C program comprising two files. The first file contains the main() function, and the second file contains other functions that the first file calls. Before the main() function definition, I've placed the following code:

#define PI 3.14159265358979323846

but the 2nd file didn't see this variable. The first file sees it fine. Then, I placed this same line in the second file (while keeping it in the first file as above), before the function definitions, but still the second file doesn't see it. Things always compile fine, but when tracing the variable PI in gdb, it shows "No symbol "PI" in current context."

How to make PI a global constant viewable across all files compiled in the application?

EDIT / UPDATE:

Based on the response so far, I've created the following file:

myheader.h

#ifndef my_header_stuff
#define my_header_stuff
    #define PI 3.1415926535897932384626433832795
#endif

and in the two files I want to see this constant PI, I've included this file as follows:

file1.c

#include <stdio.h>
#include <stdlib.h>
#include "myheader.h"
int main(void) {
  etc...
}

and file2.c

#include <stdio.h>
#include <stdlib.h>
#include "myheader.h"
double interesting_function(void) {
  etc...
}

Questions:

  1. When I use GDB to debug, b PI returns (in both files, same result) "No symbol "PI" in current context". However, the math depending on PI is computed correctly. Is there a way to view PI in gdb?

  2. Can I also include the two lines for stdio and stdlib in the myheader.h file?

  3. Can I also include any function prototypes in the myheader.h file? If I do, and then let's say I create a file3.c that doesn't require any of these prototypes because it doesn't use those functions, is any harm done?

3
  • Always put all definitions in .c files and declarations (including macros) in .h files. That should solve the problem 99% of the time. Commented Nov 29, 2011 at 1:17
  • Thanks JosephH, can you help me with the mechanics of this? See my attempt above. Commented Nov 29, 2011 at 2:50
  • See the answer that I've just posted Commented Nov 29, 2011 at 3:24

7 Answers 7

4
  1. It's normal that a macro definition doesn't show up in GDB. It's because GCC replaces each PI with the actual pi value.
  2. Yes. In your case, it doesn't hurt. If the .h file contains a prototype(they are typically called declarations) that uses a type that are defined in somewhere else, you can simply #include in your header files
  3. Yes. You can declare what ever function prototype you want and it won't do any harm in terms of the functionality of your program. Compiler won't even check the existence of the definitions of those functions unless you actually call them from somewhere else.
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks JosephH!!! Another question... I originally placed the #define directly in each file, which seemed to work fine in file1.c but not file2.c (no compile errors, but math produced wildly wrong result). Using #include is just like cut-and-paste contents into file, right? Why does the myheader.h approach produce different results--aren't both solutions just relying on #define NAME value? Or, if you can't explain it, maybe it was my debugging confusion.
I don't think you would get different results. Could you double check?
2

A macro isn't a variable, and it won't appear in gdb as a variable. Things are compiling fine because they're working fine; you just have the wrong expectations for gdb.

In general, a macro that's needed in more than one place should be defined in a header file that's included everywhere it's needed; for instance, the macro M_PI is already defined to be pi in the standard include math.h.

The other thing that you can do is to have const int PI = 3.14159etcetc; in one file and extern const int PI; in all of the others, but this is a pain because it requires the definition of the value to exist in exactly one compilation unit.

2 Comments

I would say having the value of a constant in a single place is actually a plus... ;)
It's unfortunate, but M_PI is not standard c.
1

I'd declare PI in the header file and include this header file to all source files

You should place function declarations, macros in your header file (and maybe some simple inline functions) Implementation should be placed in .c files

// I edited answer to response to your comment

3 Comments

Should the function prototypes from all files all be placed in the header file as well? I started to do this, then dropped it when I empirically found that the functions not called in a particular file don't need to have their prototypes in there, and then I wondered if something might get broken or be inefficient if this redundancy existed.
Thanks Jan. Would you use #define PI 3.14159 to declare it in the header? If so wouldn't an #include <file.h> just insert it as I currently have it? If not, how?
first of all I'd use constant M_PI from <math.h>, but if I want to declare variable for more .c files, I'd definitely do as I write above
1

You could create a global variable.

//file1.c
int my_global;


//file2.c
extern int my_global;
//code using my_global...

Note that usage of preprocessor is mostly discouraged.

Also note that M_PI define suggested by others is not available in the latest C standard (C99) so you cannot rely on it.

3 Comments

Are both of these placed before the function definitions?
@ggkmath Yes, if you want my_global to be used by those functions.
@OliCharlesworth Why not? Preprocessors are evil, or?
0

If you are working only with standard math definitions, the standard header file math.h has some good ones:

 #include <math.h>
  ...
 double area = radius * radius * M_PI;

For defining global constants, there are many methods, adequately explained in other answers.

1 Comment

It's unfortunate, but M_PI is not standard c.
0

It would be very nice if you create a header file for the file that's included in the main source file, and It is a good pratice too and you will improve your C Language skills. Imagine that we have a source file with a functions, global variables and constants that we will need in the main source file, we could create a header file for that file and put those functions there:

 #ifndef _FILE_H
 #define _FILE_H

 #include "file.h"
 #define PI 3.14
 /**
  *functions protypes here or other constants or globlal variables
  */
  void do_something(char **param1, int *param2);

 #endif

In your "file.c" file you should do the folowing:

#inlcude "file.h"

void do_something(char **param1, int *param2)
{

    /**
     *do something
     */
}

In your "main.c" file you should do :

 #include "file.h"

 /**
  *Now you can use "PI"
  */

I hope I helped somehow.

Comments

-1

the preprocessor direct will replace by actual code before compile, so in your case your first file's PI will replace by 3.14... and there is not PI symbol in symbol table of first translate unit. so the gdb will say no 'PI' symbol.

if you want use #define and don't want use header file, you need #deine PI at the beginning of each file.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.