Defining const values ​​in C

I have a C project where all the code is organized in pairs of *.c / *.h files, and I need to define a constant value in one file, which will also be used in other files. How to declare and define this value?

Should it be static const ... in the *.h file? How is extern const ... in a *.h file and defined in a *.c file? How does it matter if the value is not a primitive data type ( int , double , etc.), But a char * or struct ? (Although in my case it is double .)

Defining files inside *.h files is usually not a good idea; you need to declare things in a *.h file, but define them in a *.c file. However, the extern const ... approach seems inefficient, since the compiler will not be able to insert the value, and instead, it must access through its address all the time.

I guess the gist of this question is this: do I need to define static const ... values ​​in *.h files in C to use them in more than one place?

+4
source share
10 answers

The following rule is only to declare things in H files and define them in C files. You can declare and define in a single C file, assuming that it will be used only in this file.

By declaration, I mean to notify the compiler of its existence, but do not allocate space for it. This includes #define , typedef , extern int x , etc.

Definitions assign values ​​to declarations and allocate space for them, such as int x and const int x . This includes function definitions; including in header files, often lead to a lack of code.

I have seen too many junior programmers get confused when they put const int x = 7; to the header file and then wonder why they get a communication error for x defined more than once. I think with a minimum minimum you will need a static const int x to avoid this problem.

I would not worry too much about code speed. The main problem with computers (in terms of speed and cost) has long moved from execution speed to ease of development.

+8
source

If you need constants (real, compilation time constants), you can do this in three ways by placing them in header files (there is nothing wrong with that):

 enum { FOO_SIZE = 1234, BAR_SIZE = 5678 }; #define FOO_SIZE 1234 #define BAR_SIZE 5678 static const int FOO_SIZE = 1234; static const int BAR_SIZE = 5678; 

In C ++, I tend to use the enum method, as it can be placed in a namespace. For C, I use a macro. This, in principle, comes down to the question of taste. If you need floating point constants, you can no longer use an enum. In C ++, I use the latter method, a static const double, in this case (a note in C ++ statics would be redundant then: they became static automatically, since they are constants). In C, I will continue to use macros.

The myth that using the third method will slow down your program. I just prefer the enumeration, since the values ​​you get have rvalues ​​values ​​- you cannot get their address, which I consider to be additional security. In addition, much less boiler room code is written. The eye is focused on constants.

+3
source

Do you really need to worry about the benefits of inline? If you're not writing inline code, stick with readability. If this is really a magic number, I would use a definition; I think const is better for things like const version strings and modifications to function call arguments. However, the definition in .c to declare in the .h rule is, of course, a generally accepted convention, and I would not violate it just because you could save the search in memory.

+1
source

Typically, you do not define things as static in the header. If you define static variables in the header, each file that uses the header gets its own personal copy of what is declared static , which is the antithesis of the DRY principle: don't repeat it yourself.

So you should use an alternative. For integer types, using enum (defined in the header) is very powerful; it works well with debuggers (although better debuggers can also help with #define macros). For non-integer types, declaring an extern header (not necessarily qualified with const ) in the header, and one definition in a single C file is usually the best way.

+1
source

I can give you an indirect answer. In C ++ (unlike C) const implies static . That is, in C ++, static const is the same as const . Thus, this shows how the body of C ++ standards perceives the problem, that is, all const must be static.

0
source

I would like to see more context for your question. The value type is critical, but you left it. The meaning of the const keyword in C is pretty subtle; for example const char * p; does not mean that the pointer p is a constant; you can write p whatever you like. What you cannot write is the memory pointed to by p, and this remains true even if the value of p is changed. This is the only case that I really understand; in general, the meaning of subtle const placement eludes me. But this special case is extremely useful for function parameters , because it extracts the promise from the function that the argument of the argument indicates will not mutate.

There is another special case that everyone should know: integers. Almost always, constant named integers must be defined in the .h file as literal enumerations . enum not only allows you to naturally group related constants, but also allows you to specify the names of these constants in the debugger, which is a huge advantage.

I wrote tens of thousands of lines of C; probably hundreds if I try to track it. (wc ~ / src / c / *. c says 85 thousand, but some of them are generated, and, of course, there is a lot of C code hidden elsewhere). Apart from the two cases, I never found much use for const. I would be happy to learn a new, useful example.

0
source

for autoconf environment: you can always define constants in the configuration file. AC_DEFINE () I think this is a macro to define throughout the assembly.

0
source

To answer the gist of your question:
Normally you do NOT want to define a static variable in the header file.
This will force you to have duplicate variables in each translation unit (C files) containing the header.

variables in the header really need to be declared extern, as this is implied visibility. See this question for a good explanation.

Actually, the situation may not be so terrible, since the compiler will probably convert the type const to a literal value. But you cannot rely on this behavior, especially if optimization is disabled.

0
source

In C ++ you should always use

 const int SOME_CONST = 17; 

for constants and never

 #define SOME_CONST 17 

Definitions almost always come back and will bite you later. Consts are in the language and strongly typed, so you won’t get strange errors due to some kind of covert interaction. I would put const in the corresponding header file. As long as it is #pragma once (or #ifndef x / # define x / # endif), you will never get compilation errors.

In vanilla C, you may have compatibility issues where you should use #defines.

0
source

If you want to embed a value in your functions, you must use #define MY_MAGIC_NUMBER 0x12345678
Even a static const unsigned MY_MAGIC_NUMBER = 0x12345678 will retrieve the value from the address. Slowing performance is not a big deal if you don't cost a lot in cycles.
I use const for function arguments.

Several comments and answers were made to this answer, so I tested my assumption and looked at the generated assembly, and this answer is incorrect. Basically #define and const will give the same result.

-1
source

All Articles