27

If I declare static const variable in header file like this:

static const int my_variable = 1;

and then include this header in more than one .c files, will compilator make new instance per each file or will be "smart" enough to see it is const and will make only one instance for all the files?

I know I can make it extern and define it in one of .c files that include this header but this is what I am trying not to do.

Michał
  • 691
  • 1
  • 5
  • 22
  • There are unfortunately no named constants for arbitrary types in C. In your case you can get away with an enumeration. `enum { my_value = 1, };` This would have the effect that you probably want, enumeration constants have type `int` in C. You would not be able to take the address of such a beast. – Jens Gustedt Aug 12 '16 at 07:32

3 Answers3

22

I answered this at length here. That answer is for C++, but it holds true for C as well.

The translation unit is the individual source file. Each translation unit including your header will "see" a static const int. The static, in this context, means the scope of my_variable is limited to the translation unit. So you end up with a separate my_variable for each translation unit (".c file").

The compiler would not be "smart" to create only one instance for all files, it would be faulty, because you explicitly told it not to do so (static).

Community
  • 1
  • 1
DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • 2
    The `extern` version has the unfortunate property that you can't make the value visible to the other TUs. – Jens Gustedt Aug 12 '16 at 07:33
  • 2
    @JensGustedt: You mean compile-time visible, as opposed to run-time visible (which an `extern` variable certainly is). That is correct. Deleted that sidenote. – DevSolar Aug 12 '16 at 07:37
  • @DevSolar do you know if there is any way to force compiler to make one instance? I was told that in GCC there is an option that makes compiler comparing const variables like in my example and merge them to one but couldn't find it. – Michał Aug 12 '16 at 07:56
  • @Michał: From your question, it is a bit unclear what you use `my_variable` for, why you need there to be only one instance, and what you expect to achieve. That makes it a bit difficult to make suggestions at this point. If you just need one global variable you can take the address of, use `extern`, as it's the cleanest way to do it. If you need *compile-time visibility* (e.g. for array sizes), use either the `enum` trick pointed out by Jens, or the age-old `#define MAX_SIZE ...`. – DevSolar Aug 12 '16 at 07:59
  • @Michal: Using `extern` instead of `static`? – David Ranieri Aug 12 '16 at 07:59
  • @AlterMann is this a question ? I meant something more like compiling option not like workaround option. It means leaving `static const`. – Michał Aug 12 '16 at 08:50
  • Yes it is a question, so you can not replace `static`with `extern` – David Ranieri Aug 12 '16 at 08:51
  • The gcc option is `-fmerge-all-constants` and is non conforming as per the [doc](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html), and apply to strings and FP. Note also that there is a different behavior by default for `char *` or `char[]`. Refer to this [question](https://stackoverflow.com/questions/53077119/can-gcc-merge-duplicate-global-string-arrays) – calandoa Sep 20 '19 at 12:51
3

If you use address of that object - compiler surely creates one instance per each translation unit. If you use only value - it is probably smart enough to avoid creating of object at all - value will be inlined where need.

Sergio
  • 8,099
  • 2
  • 26
  • 52
  • I don't get you, both the address and the value of the object are not accesible outside the unit due to the `static` keyword, isn't it? – David Ranieri Aug 12 '16 at 07:39
  • @AlterMann Yes, scope of course is limited by `static` but if you e.g. want to print address of that variable or do some kind of address arithmetic (weird of course since it is not an array) - compiler can't silently optimize it and inline and obligated to allocate storage for it. – Sergio Aug 12 '16 at 07:42
  • Ah, ok, _If you use address of that object_ confuses me, I was thinking in `&my_variable` as the address of the variable, do you mean if the variable is used / not used? – David Ranieri Aug 12 '16 at 07:49
  • Actually I mean presence or absence of `&my_variable` - if there is - storage must be allocated since code needs a valid address, if there is no - compiler may insert actual value directly: `foo(my_variable)` is effectively the same as `foo(1)` (since variable is `const` and has the same value during whole program lifetime) so there is no point to allocate any memory for it. – Sergio Aug 12 '16 at 07:59
-2

I guess it will make only one instance for all files. But you can verify it by calling it in different files and check its value

shaifali Gupta
  • 380
  • 1
  • 4
  • 16