Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring a global variable `extern const int` in header but only `int` in source file

I was experimenting with GCC and found out that you can declare external variables const in header files but keep them mutable in implementation files.

EDIT: This does actually not work. The only reason I got my test code to compile was because I did not include "header.h" in "header.c".

header.h:

#ifndef HEADER_H_
#define HEADER_H_

extern const int global_variable;

#endif

header.c:

int global_variable = 17;

This seems like a very good feature to use for keeping global_variable readonly to the users of header.h but keeping them modifable by the implementation (header.c).

NOTE: The following code is just an example on how this way of declaring will prevent assignment to global_variable.

#include "header.h"

int main(void)
{
    global_variable = 34; /* This is an error as `global_variable` is declared const */
    return 0;
}

Because I have never seen technique in practise before. I start to wonder if it is valid.

Is this well defined behaivor or is this an error that GCC fails to warn me about?

like image 393
wefwefa3 Avatar asked Dec 31 '14 17:12

wefwefa3


2 Answers

const int and int are not compatible types.

For example this:

extern const int a;

int a = 2;

is not valid in C as C says that:

(C11, 6.7p4) "All declarations in the same scope that refer to the same object or function shall specify compatible types"

In your case they are not in the same scope (different translation units) but C also says that:

(C11, 6.2.7p2) "All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined."

As you are violating the rule above, you are invoking undefined behavior.

Note that C90 has the same paragraphs.

like image 165
ouah Avatar answered Oct 15 '22 06:10

ouah


A little late, but anyways.

I think this may work if you do something like this

in header.h:

#ifndef HEADER_H_
#define HEADER_H_

#ifndef HAS_GLOB_VAR
extern const int global_variable;
#endif

#endif

and if you need to include the header in the file that actually defines the variable (header.c) you do something like

#define HAS_GLOB_VAR
#include "header.h"

int global_variable = 17;

...

On the other files you just include the header and don't define HAS_GLOB_VAR.

like image 21
hello_hell Avatar answered Oct 15 '22 07:10

hello_hell