Using enums from statically linked libraries - c

I've seen that enums do not get exported from libraries in gcc. That is, if I have enum foo in lib1.c and use it to build lib.a, I cannot use enum foo in myprog.c, which links against the library.
As such, does that mean that if I want to use enum foo, I have to redefine it in myprog.c? Also, is there any way to export the enums for a library so that my program can make use of them?

This is "normal behavior". Enums are compile-time constants, not variables that are put in a binary or exported.
Typically, when using a library, you would include a header file with the definitions of the functions that you will use and the enumerations used in/with this library.

This is what you do:
Create one (or more) header files that contains the declaration for lib1.c that you want other code to be able to use:
lib1.h:
#ifndef LIB1_H_
#define LIB1_H_
enum Foo {
Bar =1
};
void do_something(enum Foo a);
#endif
In the lib1.c source code, you include this header file, use the enum you defined, and implement the do_something() function.
Build lib1.c to produce your library, lib1.a
Anyone that wants to use your lib1.a needs two thing:
The library, lib1.a
The lib1.h header file for the library.
The source code that need to use functionality from lib1.a, include the same headerfile lib1.h , where the enum, functions, and other things are declared, and you link to the lib1.a

Related

Hiding non-API symbols in library

Suppose I have a library foo which consists of the modules foo and util and has the following source tree:
foo/
foo.c
foo.h
util.c
util.h
The public API of the library is defined in foo.h and all global identifiers are properly prefixed with foo_ or util_. The module util is only used by foo. To prevent name clashes with other modules named util I want to create a (static) library in which only identifiers from module foo are visible. How can I do this?
Edit: I have searched the internet quite extensively but surprisingly this seems to be one of those unsolved problems in computer science.
There are probably other possible approaches, but here's one:
You might consider including the file util.c within foo.c and making all the util functions / globals static. i.e.:
#include "util.c"
// ...
This works the same as *.h files, it simply ports the whole source into foo.c, nesting util.c and making all the static data available.
When I do this, I rename the file to .inc (i.e. util.c => util.inc)...
#include "util.inc"
// ...
...it's an older convention I picked up somewhere, though it might conflict with assembler files, so you'll have to use your own discretion.
EDIT
Another approach might require linker specific directives. For example, this SO answer details GNU's ld to achieve this goal. There are other approaches as well, listed in that same thread.
The following is GCC-specific.
You can mark each utility function with
__attribute__((visibility ("hidden")))
which will prevent it from being linked to from another shared object.
You can apply this to a series of declarations by surrounding them with
#pragma GCC visibility push(hidden)
/* ... */
#pragma GCC visibility pop
or use -fvisibility=hidden when compiling the object, which applies to declarations without an explicit visibility (e.g. neither __attribute__((visibility)) nor #pragma GCC visibility).
Before each variable and function declaration in util.h, define a macro constant which renames the declared identifier by adding the library prefix foo_, for instance
#define util_x foo_util_x
extern int util_x;
#define util_f foo_util_f
void util_f(void);
...
With these definitions in place, no other parts of the code need to be changed, and all global symbols in the object file util.o will be prefixed with foo_. This means that name collisions are less likely to occur.

Keep functions private into a lib in C

I recently had to face a fairly complex issue regarding lib management, but I would be very surprised to be the first one.
Let's imagine you are creating a library (static or dynamic) called lib1 in C. Inside lib1 are a few functions that are exposed through an API, and a few other ones which remain private.
Ideally, the private functions would be static. Unfortunately, let's assume one of the source files, called extmod.c, come from another project, and it would be beneficial to keep it unmodified. Therefore, it becomes unpractical to static the functions it defines.
As a consequence, all the functions defined into extmod are present into lib1 ABI, but not the API, since the relevant *.h is not shipped. So no one notice.
Unfortunately, at later stage, someone wants to link both lib1 and another lib2 which also includes extmod. It results in a linking error, due to duplicate definitions.
In C++, the answer to this problem would be a simple namespace. In C, we are less lucky.
There are a few solutions to this problem, but I would like to probe if anyone believes to have found an efficient and non-invasive way. By "non-invasive", I mean a method which avoids if possible to modify extmod.c.
Among the possible workaround, there is the possibility to change all definitions from extmod.c using a different prefix, effectively emulating namespace. Or the possibility to put the content of extmod.c into extmod.h and static everything. Both method do extensively modify extmod though ...
Note that I've looked at this previous answer, but it doesn't address this specific concern.
You could implement your 'different prefix' solution by excluding extmod.c from your your build and instead treating it as header file in a way. Use the C pre-processor to effectively modify the file without actually modifying it. For example if extmod.c contains:
void print_hello()
{
printf("hello!");
}
Exclude this file from your build and add one called ns_extmod.c. The content of this file should look like this:
#define print_hello ns_print_hello
#include "extmod.c"
On compilation, print_hello will be renamed to ns_print_hello by the C pre-processor but the original file will remain intact.
Alternatively, IF AND ONLY IF the function are not called internally by extmod.c, it might work to use the preprocessor to make them static in the same way:
#define print_hello static print_hello
#include "extmod.c"
This should work for you assuming you have control over the build process.
One way you can do prefixing without actually editing extmod.c is as follows:
Create a new header file extmod_prefix.h as:
#ifndef EXTMOD_PREFIX_H
#define EXTMOD_PREFIX_H
#ifdef LIB1
#define PREFIX lib1_
#else
#ifdef LIB2
#define PREFIX lib2_
#endif
#endif
#define function_in_extmod PREFIX##function_in_extmod
/* Do this for all the functions in extmod.c */
#endif
Include this file in extmod.h and define LIB1 in lib1's build process and LIB2 in lib2.
This way, all the functions in extmod.c will be prefixed by lib1_ in lib1 and lib2_ in lib2.
Here's the answer (in the form of a question). The relevant portion:
objcopy --prefix-symbols allows me to prefix all symbols exported by
an object file / static library.

Using macros in C to change behavior in other C files

Is it possible to define a macro in a C file, and then change behavior of another C file using this definition?
For instance, suppose we have a file named b.c:
#include <stdio.h>
#define ABC
void function() {
printf("b.c\n");
}
And another file named a.c:
#include <stdio.h>
int main() {
#ifdef ABC
printf("b.c defined this\n");
#endif
printf("a.c\n");
}
These files are compiled together. I want the definition of ABC in b.c to influence a.c.
I know I was supposed to be using a header file, but I don't want to do that. Is there another way to achieve this?
In my scenario, b.c is a sort of sub-application that will complement the behavior of a.c, and it should also be able to override behavior in there.
Is there an alternative to macros that can achieve this?
Use global variables or use callbacks. The "best" solution depends on precisely how much flexibility you need.
As others said, you can't do it.
Your options:
1. Don't use macros. Generally, it's good advice. There are some things that can't be done without macros, but normally you don't see them. You'll get better code without macros.
2. Define the macro in a header file, which is included by both C files.
It doesn't work the way you describe.
#define ABC only defines ABC within the scope of the b.c file, and does not impact other files (unless b.c is #included).
The only way to define ABC within the scope of a.c file without header files is to define ABC using the command line arguments of the compiler: gcc -D ABC ...
No this is not possible this way. But you may instruct compiler to define a symbol using command line options

How to declare an inline function in C99 multi-file project?

I want to define an inline function in a project, compiled with c99. How can I do it?
When I declare the function in a header file and give the detail in a .c file, the definition isn't recognized by other files. When I put the explicit function in a header file, I have a problem because all .o files who use it have a copy of the definition, so the linker gives me a "multiple definition" error.
What I am trying to do is something like:
header.h
inline void func()
{
do things...
}
lib1.c
#include "header.h"
...
lib2.c
#include "header.h"
with a utility which uses both lib1.o and lib2.o
Unfortunately not all compilers are completely complying to C99 in that point even if they claim that they'd be.
An conforming way to do this is
// header file. an inline definition alone is
// not supposed to generate an external symbol
inline void toto(void) {
// do something
}
// in one .c file, force the creation of an
// external symbol
extern inline void toto(void);
Newer versions of gcc, e.g, will work fine with that.
You may get away with it for other compilers (pretenders) by defining something like
#ifdef PRETENDER
# define inlDec static
# define inlIns static
#else
# define inlDec
# define inlIns extern
#endif
// header file. an inline declaration alone is
// not supposed to generate an external symbol
inlDec inline void toto(void) {
// do something
}
// in one .c file, force the creation of an
// external symbol
inlIns inline void toto(void);
Edit:
compilers with C99 support (usually option -std=c99) that I know of
gcc (versions >= 4.3 IIRC) implements
the correct inline model
pcc is also correct
ggc < 4.3 needs a special option to
implement the correct model,
otherwise they use their own model
that results in multiple defined
symbols if you are not careful
icc just emits symbols in every unit
if you don't take special care. But
these symbols are "weak" symbols, so
they don't generate a conflict. They
just blow up your code.
opencc, AFAIR, follows the old gcc specific model
clang doesn't emit symbols for inline functions at all, unless you have an extern declaration and you use the function pointer in one compilation unit.
tcc just ignores the inline keyword
If used by itself, in C99 inline requires that the function be defined in the same translation unit as it's being used (so, if you use it in lib1.c, it must be defined in lib1.c).
You can also declare a method as static inline (and put the definition in a header file shared between two source files). This avoids the multiple-definition issue, and lets the compiler inline the file across all the translation units where it's used (which it may or may not be able to do if you just declare the function in one translation unit).
See: http://www.greenend.org.uk/rjk/2003/03/inline.html
I think you don't need to use the inline word when you are defining and declaring the function inside the Header file, the compiler usually takes it as inline by default unless it's too long, in which case it will be smart enough to treat it as a normal function.
I think the multiple definition may be caused by the lack of a Include Guard in the Header file.
You should use something like this in the header:
#ifndef HEADERNAME_H
#define HEADERNAME_H
void func()
{
// do things...
}
#endif

How to structure #includes in C

Say I have a C program which is broken to a set of *.c and *.h files. If code from one file uses functions from another file, where should I include the header file? Inside the *.c file that used the function, or inside the header of that file?
E.g. file foo.c includes foo.h, which contains all declarations for foo.c; same for bar.c and bar.h. Function foo1() inside foo.c calls bar1(), which is declared in bar.h and defined in bar.c. Now the question is, should I include bar.h inside foo.h, or inside foo.c?
What would be a good set of rules-of-thumb for such issues?
You should include foo.h inside foo.c. This way other c files that include foo.h won't carry bar.h unnecessarily. This is my advice for including header files:
Add include definitions in the c files - this way the file dependencies are more obvious when reading the code.
Split the foo.h in two separate files, say foo_int.h and foo.h. The first one carries the type and forward declarations needed only by foo.c. The foo.h includes the functions and types needed by external modules. This is something like the private and public section of foo.
Avoid cross references, i.e. foo references bar and bar references foo. This may cause linking problems and is also a sign of bad design
As others have noted, a header foo.h should declare the information necessary to be able to use the facilities provided by a source file foo.c. This would include the types, enumerations and functions provided by foo.c. (You don't use global variables, do you? If you do, then those are declared in foo.h too.)
The header foo.h should be self-contained and idempotent. Self-contained means that any user can include foo.h and not need to worry about which other headers may be needed (because foo.h includes those headers). Idempotent means that if the header is included more than once, there is no damage done. That is achieved by the classic technique:
#ifndef FOO_H_INCLUDED
#define FOO_H_INCLUDED
...rest of the contents of foo.h...
#endif /* FOO_H_INCLUDED */
The question asked:
File foo.c includes foo.h, which contains all declarations for foo.c; same for bar.c and bar.h. Function foo1() inside foo.c calls bar1(), which is declared in bar.h and defined in bar.c. Now the question is, should I include bar.h inside foo.h, or inside foo.c?
It will depend on whether the services provided by foo.h depend on bar.h or not. If other files using foo.h will need one of the types or enumerations defined by bar.h in order to use the functionality of foo.h, then foo.h should ensure that bar.h is included (by including it). However, if the services of bar.h are only used in foo.c and are not needed by those who use foo.h, then foo.h should not include bar.h
I would only include header files in a *.h file that required for the header file itself. Header files that are needed for a source file, in my opinion, should be included in the source file so that the dependencies are obvious from the source. Header files should be be built to handle multiple inclusion so you could put it in both if required for clarity.
Using the examples of foo.c and foo.h I've found these guidelines helpful:
Remember that the purpose of foo.h is to facilitate the use of foo.c, so keep it as simple, organized, and self-explanatory as possible. Be liberal with comments that explain how and when to use the features of foo.c -- and when not to use them.
foo.h declares the public features of foo.c: functions, macros, typedefs, and (shudder) global variables.
foo.c should #include "foo.h -- see discussion, and also Jonathan Leffler's comment below.
If foo.c requires additional headers for it to compile, include them in foo.c.
If external headers are required for foo.h to compile, include them in foo.h
Leverage the preprocessor to prevent foo.h from being included more than once. (See below.)
If for some reason an external header will be required in order for another .c file to use the features in foo.c, include the header in foo.h to save the next developer from unnecessary debugging. If you're averse to this, consider adding macro that will display instructions at compile-time if the required headers haven't been included.
Don't include a .c file within another .c file unless you have a very good reason and document it clearly.
As kgiannakakis noted, it's helpful to separate the public interface from the definitions and declarations needed only within foo.c itself. But rather than creating two files, it's sometimes better to let the preprocessor do this for you:
// foo.c
#define _foo_c_ // Tell foo.h it's being included from foo.c
#include "foo.h"
. . .
// foo.h
#if !defined(_foo_h_) // Prevent multiple inclusion
#define _foo_h_
// This section is used only internally to foo.c
#ifdef _foo_c_
. . .
#endif
// Public interface continues to end of file.
#endif // _foo_h_ // Last-ish line in foo.h
I include the most minimal set of headers possible in the .h file, and include the rest in the .c file. This has the benefit of sometimes reducing compilation times. Given your example, if foo.h doesn't really need bar.h but includes it anyway, and some other file includes foo.h, then that file will be recompiled if bar.h changes, even though it may not actually need or use bar.h.
The .h file should define the public interface (aka the api) to the functions in the .c file.
If the interface of file1 uses the interface of file2 then #include file2.h in file1.h
If the implementation in file1.c makes use of stuff in file2.c then file1.c should #include file2.h.
I must admit though that - because I always #include file1.h in file1.c - I normally wouldn't bother #including file2.h directly in file1.c if it was already #included in file1.h
If you ever find yourself in the situation where two .c files #include each others .h files then it is a sign that modularity has broken down and you ought to think about restructuring things a bit.

Resources