If I'm planning to use something that is only provided after declaring _GNU_SOURCE, do I need to declare _GNU_SOURCE at the top of all source files in the project?
Is it safe to only declare it at the top of any source files that require it?
My initial concern is related to type declarations... it's of course possible that a struct changes shape after defining _GNU_SOURCE, but is that likely, or is it guaranteed that such things "will not change shape"?
For example, if I use a struct to declare a variable in one file (with _GNU_SOURCE), and then use that variable in another (without _GNU_SOURCE), is guaranteed that I will not run into problems?
In this case I'm after pthread_tryjoin_np().
It is safe to declare it only in files that need it.
After all, the whole point is that some code would break if was defined, but it still needs to be linked with code that uses it.
As #IanAbbott notes below, exception is when you use some of the varying types in your interface. Then you need to keep the definition consistent for the modules that use it. E.g. off_t becomes, under _GNU_SOURCE, alias for off64_t, so if you then include the same header with _GNU_SOURCE turned off, it will define different functions.
That said, within a project there is really not much reason not to define it everywhere, because once you define it in any file, you depend on it. So defining it locally only helps anything if it is in an optional component or if you have alternates for other systems that use functions specific to those other systems instead.
Related
I am writing a C (shared) library. It started out as a single translation unit, in which I could define a couple of static global variables, to be hidden from external modules.
Now that the library has grown, I want to break the module into a couple of smaller source files. The problem is that now I have two options for the mentioned globals:
Have private copies at each source file and somehow sync their values via function calls - this will get very ugly very fast.
Remove the static definition, so the variables are shared across all translation units using extern - but now application code that is linked against the library can access these globals, if the required declaration is made there.
So, is there a neat way for making private global variable shared across multiple, specific translation units?
You want the visibility attribute extension of GCC.
Practically, something like:
#define MODULE_VISIBILITY __attribute__ ((visibility ("hidden")))
#define PUBLIC_VISIBILITY __attribute__ ((visibility ("default")))
(You probably want to #ifdef the above macros, using some configuration tricks à la autoconfand other autotools; on other systems you would just have empty definitions like #define PUBLIC_VISIBILITY /*empty*/ etc...)
Then, declare a variable:
int module_var MODULE_VISIBILITY;
or a function
void module_function (int) MODULE_VISIBILITY;
Then you can use module_var or call module_function inside your shared library, but not outside.
See also the -fvisibility code generation option of GCC.
BTW, you could also compile your whole library with -Dsomeglobal=alongname3419a6 and use someglobal as usual; to really find it your user would need to pass the same preprocessor definition to the compiler, and you can make the name alongname3419a6 random and improbable enough to make the collision improbable.
PS. This visibility is specific to GCC (and probably to ELF shared libraries such as those on Linux). It won't work without GCC or outside of shared libraries.... so is quite Linux specific (even if some few other systems, perhaps Solaris with GCC, have it). Probably some other compilers (clang from LLVM) might support also that on Linux for shared libraries (not static ones). Actually, the real hiding (to the several compilation units of a single shared library) is done mostly by the linker (because the ELF shared libraries permit that).
The easiest ("old-school") solution is to simply not declare the variable in the intended public header.
Split your libraries header into "header.h" and "header-internal.h", and declare internal stuff in the latter one.
Of course, you should also take care to protect your library-global variable's name so that it doesn't collide with user code; presumably you already have a prefix that you use for the functions for this purpose.
You can also wrap the variable(s) in a struct, to make it cleaner since then only one actual symbol is globally visible.
You can obfuscate things with disguised structs, if you really want to hide the information as best as possible. e.g. in a header file,
struct data_s {
void *v;
};
And somewhere in your source:
struct data_s data;
struct gbs {
// declare all your globals here
} gbss;
and then:
data.v = &gbss;
You can then access all the globals via: ((struct gbs *)data.v)->
I know that this will not be what you literally intended, but you can leave the global variables static and divide them into multiple source files.
Copy the functions that write to the corresponding static variable in the same source file also declared static.
Declare functions that read the static variable so that external source files of the same module can read it's value.
In a way making it less global. If possible, best logic for breaking big files into smaller ones, is to make that decision based on the data.
If it is not possible to do it this way than you can bump all the global variables into one source file as static and access them from the other source files of the module by functions, making it official so if someone is manipulating your global variables at least you know how.
But then it probably is better to use #unwind's method.
This is a case of "static const” vs “#define” in C" for embedded systems.
On large/mid projects with "passed-down" code and modules, what is the best practice on writing constant parameters for your include files, modules, etc?
In a code "passed-down" where you don't know if the names you're choosing are defined in some other included file or might be called with extern or as macros in some other file that might include your file.
Having these 3 options:
static const int char_height = 12;
#define CHAR_HEIGHT 12
enum { char_height = 12 };
which one would be better (on an embedded system with unknown memory constraints)?
The original code uses mainly #define's for this, but these kind of constants are haphazardly implemented in several ways (and at different locations even in the same files) since it seems several people developed this demo software for a certain device.
Specifically, this is a demo code, showing off every hardware and SDK feature of a certain device.
Most of the data I'm thinking about is the kind used to configure the environment: screen dimensions, charset characteristics, something to improve the readability of the code. Not on the automatic configuration a compiler and pre-processor could do. But since there's a lot of code in there and I'm afraid of global name conflicts, I'm reluctant to use #define's
Currently, I'm considering that it would be better to rewrite the project from scratch and re-implement most of the already written functions to get their constants from just one c file or reorganize the constants' implementation to just one style.
But:
This is a one person project (so it would take a lot of time to re-implement everything)
The already implemented code works and it has been revised several times. (If it's not broken...)
Always consider readability and memory constraints. Also, macros are simply copy/paste operations that occur before compilation. With that being said I like to do the following:
I define all variables that are constant as being static const if they are to be used in one c file (e.g. not globally accessible across multiple files). Anything defined as const shall be placed in ROM when at file scope. Obviously you cannot change these variables after they're initialized.
I define all constant values using #define.
I use enumerations where it adds to readability. Any place where you have a fixed range of values I prefer enumerations to explicitly state the intent.
Try to approach the project with an object oriented perspective (even though c isn't OO). Hide private functions (don't create a prototype in the header), do not use globals if you can avoid it, mark variables that should only reside in one c module (file) as static, etc.
They are 3 different things that should be used in 3 different situations.
#define should be used for constants that need to be evaluated at compile time. One typical example is the size of a statically allocated array, i.e.
#define N 10
int x[N];
It is also fine to use #define all constants where it doesn't matter how or where the constant is allocated. People who claim that it is bad practice to do so only voice their own, personal, subjective opinions.
But of course, for such cases you can also use const variables. There is no important difference between #define and const, except for the following cases:
const should be used where it matters at what memory address a constant is allocated. It should also be used for variables that the programmer will likely change often. Because if you used const, you an easily move the variable to a memory segment in EEPROM or data flash (but if you do so, you need to declare it as volatile).
Another slight advantage of const is that you get stronger type safety than a #define. For the #define to get equal type safety, you have to add explicit type casts in the macro, which might get a bit harder to read.
And then of course, since consts (and enums) are variables, you can reduce their scope with the static keyword. This is good practice since such variables do not clutter down the global namespace. Although the true source of name conflicts in the global namespaces are in 99% of all cases caused by poor naming policies, or no naming policies at all. If you follow no coding standard, then that is the true source of the problem.
So generally it is fine to make constants global when needed, it is rather harmless practice as long as you have a sane naming policy (preferably all items belonging to one code module should share the same naming prefix). This shouldn't be confused with the practice of making regular variables global, which is always a very bad idea.
Enums should only be used when you have several constant values that are related to each other and you want to create a special type, such as:
typedef enum
{
OK,
ERROR_SOMETHING,
ERROR_SOMETHING_ELSE
} error_t;
One advantage of the enum is that you can use a classic trick to get the number of enumerated items as another compile-time constant "free of charge":
typedef enum
{
OK,
ERROR_SOMETHING,
ERROR_SOMETHING_ELSE,
ERRORS_N // the number of constants in this enum
} error_t;
But there are various pitfalls with enums, so they should always be used with caution.
The major disadvantage of enum is that it isn't type safe, nor is it "type sane". First of all, enumeration constants (like OK in the above example) are always of the type int, which is signed.
The enumerated type itself (error_t in my example) can however be of any type compatible with char or int, signed or unsigned. Take a guess, it is implementation-defined and non-portable. Therefore you should avoid enums, particularly as part of various data byte mappings or as part of arithmetic operations.
I agree with bblincoe...+1
I wonder if you understand what the differences are in that syntax and how it can/might affect implementation. Some folks may not care about implementation but if you are moving into embedded perhaps you should.
When bblincoe mentions ROM instead of RAM.
static const int char_height = 12;
That should, ideally, consume .text real estate and pre-init that real estate with the value you specified. Being const you wont change it but it does have a placeholder? now why would you need a placeholder for a constant? think about that, certainly you could hack the binary down the road for some reason to turn something on or off or change a board specific tuning parameter...
Without a volatile though that doesnt mean that compiler has to always use that .text location, it can optimize and put that value in as instructions directly or even worse optimize math operations and remove some math.
The define and enum do not consume storage, they are constants that the compiler chooses how to implement, ultimately those bits if they are not optimized away, land somewhere in .text sometimes everywhere in .text, depends on the instruction set how its immediates work the specific constant, etc.
So define vs enum is basically do you want to pick all the values or do you want the compiler to pick some values for you, define if you want to control it enum if you want the compiler to choose the values.
So it really isnt a best practice thing at all it is a case of determining what your program needs to do and choosing the appropriate programming solution for that situation.
Depending on the compiler and the target processor, choosing volatile static const int vs not doing that can affect the rom consumption. But it is a very specific optimization, and not a general answer (and has nothing to do with embedded but with compiling in general).
Dan Saks explains why he prefers the enumeration constant in these articles, Symbolic Constants and Enumeration Constants vs Constant Objects. In summary, avoid macros because they don't observe the usual scope rules and the symbolic names are typically not preserved for symbolic debuggers. And prefer enumeration constants because they are not susceptible to a performance penalty that may affect constant objects. There is a lot more details in the linked articles.
Another thing to considerer is performance. A #define constant can usually be accessed faster than a const variable (for integers) since the const will need to be fetched from ROM (or RAM) and the #define value will usually be an immediate instruction argument so it is fetched along with the instruction (no extra cycles).
As for naming conflicts, I like to use prefixes like MOD_OPT_ where MOD is the module name OPT means that the define is a compile-time option, etc. Also only include the #defines in your header files if they're part of the public API, otherwise use an .inc file if they're needed in multiple source files or define them in the source file itself if they're only specific to that file.
My project incorporates a stack, which has a number of user-defined types (typedef). The problem is that many of these type definitions conflict with our in-house type definitions. That is, the same symbol name is being used. Is there any way to protect against this?
The root of the problem is that to use the stack in our application, or wrapper code, as the case may be, a certain header file must be included. This stack header file in turn includes the stack provider's types definition file. That's the problem. They should have included their type definition file via a non-public include path, but they didn't. Now, there are all sorts of user-defined type conflicts for very common names, such as BYTE, WORD, DWORD, and so forth.
Since you probably can't easily change the program stack you are using, you will have to start with your own code.
The first thing to do is (obviously) to limit the number of names in the global namespace, as far as possible. Don't use global variables, just use static ones, as an example.
The next step is to adopt a naming convention for your code modules. Suppose you have an "input module" in the project. You could then for example prefix all functions in the input module "inp".
void inp_init (void);
void inp_get (int input);
#define INP_SOMECONSTANT 4
typedef enum
{
INP_THIS,
INP_THAT,
} inp_something_t;
And so on. Whenever these items are used elsewhere in the code, they will not only have a unique identifier, it will also be obvious to the reader which module they belong to, and therefore what purpose they have. So while fixing the namespace conflicts, you gain readability at the same time.
Something like the above could be the first steps to implementing a formal coding standard, something you need to do sooner or later anyway as a professional programmer.
I suggest you define a wrapping header that redefines all of the functions and structures exported by the stack in terms of your own types. This header is then included in your system files but not in the stack files (where it would conflict). You can then compile and link but there is a weak point at the interface. If you select your types correctly in your redefinitions, it should work correctly, leaving only an maintenance problem on each update from the stack supplier...
I think that I've come up with a reasonable workaround, for the time being, but as Lundin stated, a formal coding standard is needed for a long-term solution.
Basically what I did was to move the inclusion of the required stack header file to before the inclusion of our in-house type definitions file. Then, between those two includes I added a compiler macro to set a defined constant dependent on whether the stack's header file single-include protection definition has been defined. Then, I used that conditional defined constant as a conditional compile option in our in-house type definition file to prevent the conflicting data-types from being re-defined. It's a little sloppy, but progress can only be made in incremental steps.
Suppose I would like to declare a set of constants in C (representing error codes of an application). how would you divide them into files ? would you use enum in external file and include it ?
Thanks,
James
Yes, #defines or enums in a .h file is the way to go. Enums are useful if you're debugging with a debugger like gdb as you'll see a more descriptive value than a number.
If it's a set of related numeric values, then an enum is the correct approach. If the values are C strings or otherwise not representable by an enum (or if they don't sensibly form a set of related values), you can use one of two approaches.
Either use preprocessor #define statements, or use extern const-marked variables. The former is resolved at compile-time, so you can use it to specify array lengths or to actively call code when used. The latter, however, allows you to change the value of the constant (by specifying it in a .c file rather than a .h file) without having to recompile every file that uses it.
Because extern const-marked variables can be changed in that fashion, they are preferable in code that is reused across many projects, or code that is distributed as a library. Changes to the library are then possible without forcing programs to be recompiled.
If it's a set of values an enumeration declared in a header file would suffice (some people use #defines but since the value doesn't matter an enumeration works just fine in this case). If you simply want to compare to error codes this is a good method.
Declared one structure STRUCT_ABC in a header file abc.h
Included abc.h in abc.c file and used STRUCT_ABC in some function inside abc.c.
Another file def.c does not include abc.h. But in def.c, i again defined a structure with same name, i.e. STRUCT_ABC, but with different contents.
Both abc.c & def.c are under same library and control first comes in abc.c during runtime.
Control goes from abc.c to def.c and comes back, say multiple times.
Can this give a runtime error always, or sometimes this might work?
It certainly won't cause you a runtime error.
The compiler will pick up the definition of the structure it saw when compiling the file that uses the structure, so you shouldn't get any compilation or linker errors either.
Really, though, if you want to use the same structure in 2 places, you're better off defining it in a single header and #includeing it in multiple .c files. It will make maintenance easier (you only need to update the structure once) and you'll know for sure which definition you're using (since there's only one).
If my memory is correct, this is compiler dependent (depends on how much decoration is applied to the definitions of the struct), but it would usually work (though we'd need more specifics to be sure). As long as the two units of code don't know about the conflicting declaration in the other unit, the compiler isn't really using the same name for each struct, and eventually it compiles down to an unnamed memory block in any event. Don't go passing the struct from abc to def and expect it to work (it will probably error on compile if you try), but as long as they aren't stepping on each others' toes it should be fine.
Like the other posters stated, if you are strictly defining the structs in both places, you should be okay. However, you're asking for trouble, particular if def.c ever needs to include abc.h.
From your description, it isn't 100% clear to me whether STRUCT_ABC is the struct name or an instance name. If you are defining instances of the structs in both files (outside of a function), and the instances are named the same you would have a compile problem unless you declare one or both instances static.
The errors should be compile errors, unless you trick a function expecting one STRUCT_ABC into using the other other (ie through a pointer).