1

I would like to know how make the division between declaration and definition. I read few related with this topic question but for now I can do this only in basic funtion. The problem is when I try to declare constant global variable in header file and I want use this constant in the function which have declaration in the same place but definition in other files. I have 2 files with .c extension and one with .h extension.

File main_lib.h consist:

#ifndef _MAIN_LIB_H_
#define _MAIN_LIB_H_
const int N_POINTS=10;

struct Point{
    int x;
    int y;
};
void fill_random(struct Point points[], int n);
void closest(struct Point points[], int n, struct Point* p);

#endif /* _MAIN_LIB_H_ */

File main_lib.c consist:

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include "main_lib.h"

    void fill_random(struct Point points[], int n){
...
    }
    void closest(struct Point points[], int n, struct Point* p){
...
    }

And the last file named main.c consist:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "main_lib.h"

int main()
{
    srand(time(0));
    struct Point random_points[N_POINTS];

    struct Point *p;
    p=&random_points[0];

    fill_random(p,N_POINTS);
    closest(p,N_POINTS,p);

    return 0;
}

The question is how to correct this code to run it without error status. Thanks a lot for any help.

J. Deniro
  • 11
  • 1
  • 1
    `const int N_POINTS=10;` in the header (and twice included) will probably give a link error (something like multiple definitions). Instead, you can do this: `extern const in N_POINTS;` in the header and `const int N_POINTS=10;` in _one_ C source. The linker will ensure that all other C sources will be linked against the same `N_POINTS`. – Scheff's Cat Jan 10 '18 at 12:28
  • Please, consider that `const` does not mean "constant" as you might think. Instead, it should be understood as "read-only". There are no constants in C except the literals (e.g. `123`) and values defined by an `enum`. (My personal memory hook: everything what you _may_ use e.g. as size of a global array declaration...) – Scheff's Cat Jan 10 '18 at 12:32
  • Is `extern` mostly useful in this context only? – YouHaveaBigEgo Jan 10 '18 at 12:33
  • 1
    @Scheff Detail: In C, `123` is an integer _constant_. C has 2 _literals_: _string literal_ and _compound literal_ - both of which may have their address taken, unlike _constants_. (Different from C++) – chux - Reinstate Monica Jan 10 '18 at 12:36
  • @YouHaveaBigEgo Depends on how you consider it - you declare functions as extern, too, so they are accessible from outside the file - just that extern is the default... – Aconcagua Jan 10 '18 at 12:38
  • @chux I must admit that this term "literal" confuses me a bit. I tried to say it correct but I fully agree with your argument. I once tried to clarify this in google and Wikipedia but with less luck. This term is used in too many contexts with slightly different meanings... (But I don't give up. Once I will get it...) – Scheff's Cat Jan 10 '18 at 12:41
  • @YouHaveaBigEgo My rule of thumb: If its globally declared and its not explicitly something else (e.g. `static`) or restricted by a previous declaration it's `extern`. The answers to [SO: How to correctly use the extern keyword in C](https://stackoverflow.com/q/496448/7478597) probably explain it better. – Scheff's Cat Jan 10 '18 at 12:43
  • 1
    @Scheff Agree about "literal" confusion. I try to use as the C spec as this is a C post - C spec uses it in a consistent manner/context - literally ;-) – chux - Reinstate Monica Jan 10 '18 at 12:48

2 Answers2

3

The problem is when I try to declare constant global variable in header file ...

how to correct this code to run it without error status(?)

Instead, declare extern in main_lib.h @Scheff. This would be the same if the global variable was non-const or volatile.

// const int N_POINTS=10;
extern const int N_POINTS;

Define it once and only in main_lib.c

// add
const int N_POINTS=10;
Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

A method I often use is:

// lib.h
#ifndef EXTERN
#define EXTERN extern
#endif
EXTERN int myInt;

// lib.c
#include "lib.h"

// main.c
#define EXTERN
#include "lib.h"

myInt will now be known in all modules in which lib.h is included but will only be declared once in main.c. Usefull when you have lots of includes.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41