Dead code removal if implementation is overwritten - c

I'm in the process of writing a library that provides a sha256 implementation. The library will be given to vendors that may want to provide their own sha256 functions that are optimized for their platform. So, the API of this library allows the client to pass in function pointers to their sha256 code.
int mylib_set_sha256_impl( /* function pointers */ );
Henceforth, all algorithms will use the function pointers provided internally instead of the stock sha256 code provided by the library.
The question is: how can I facilitate dead code removal during link time, such that the default sha256 implementation in this library is removed??
This is an API design question as much as it is a compiler-optimization question.

There are no special requirement as far as linker is concerned, and no weak aliasing need be considered.
The basic rule is: As long as the user code doesn't reference any symbols in a given .c or .s file that you linked into your library, the said file's contents won't end up in the executable.
In the scenario you describe, your functions may never become dead code since your "live" code perhaps references their addresses to set up default function pointer values. To make sure that doesn't happen, you have to do the following:
Refer to the replaceable functions only from within a user-callable optional default_init function.
The default_init must never be called anywhere in your code, neither must any of the functions be referenced anywhere but within default_init.
Have the replaceable functions, and the init function, put into at least one .c or assembly file that is not used for any of the other code.
For your user to replace all the functions, they simply have to never call the default_init function. If you wish functions to be replaceable one-by-one, you have to, additionally:
Have each replaceable function in its own .c file.
Have the user not call the default_init directly, but pass the desired default or user-provided implementations to your init function.
What you're doing, in effect, isn't "overwriting" any implementation, but simply not using it at all.
Example (include guards omitted for clarity):
// api.h
void api_fun1(void);
void api_fun2(void);
void api_default_init(void);
void api_user_init(void (*f1)(void), void (*f2)(void));
void api_use_funs(void);
// api_internal.h
extern void (*api_f1)(void);
extern void (*api_f2)(void);
// common.c
#include "api.h"
#include "api_internal.h"
void (*api_f1)(void);
void (*api_f2)(void);
void api_user_init(void (*f1)(void), void (*f2)(void)) {
api_f1 = f1;
api_f2 = f2;
}
void api_use_funs(void) {
api_f1();
api_f2();
}
// api_fun1.c
#include "api.h"
void api_fun1(void) {}
// api_fun2.c
#include "api.h"
void api_fun2(void) {}
// api_default_init.c
#include "api.h"
#include "api_internal.h"
void api_default_init(void) {
api_f1 = api_fun1;
api_f2 = api_fun2;
}
Let's say that the user wants to override api_fun2 with their own:
// main.c
#include "api.h"
#include <stdio.h>
void my_fun2() {
printf("%s\n", __FUNCTION__);
}
int main() {
api_user_init(api_fun1, my_fun2);
api_use_funs();
}

Related

Make function visible only within a library, not in API

I am writing a C99 library that is distributed among several files, e.g.
// core.h
void my_private_fn();
void API_my_public_fn();
// core.c
#include "core.h"
void my_private_fn() {
do_something();
}
void API_my_public_fn() {
do_something_else();
}
// module_a.h
#include "core.h"
void API_useful_thing();
// module_a.c
#include "module_a.h"
void API_useful_thing() {
my_private_fn();
}
I want only the API_ prefixed functions to be visible by a program using the library, but I also need to expose my_private_fn in core.h in order to be used by module_a.c. Is there a way in C to make my_private_fn only visible within the library?
If the function had to only be visible in the compilation unit where it is defined, then you could declare it static. Because C language offers few possible scopes: a symbol can have only 3 scopes:
local to a block (the block can be a function or a block inside a function)
static scope (static declaration outside of a function): the symbol is only visible in the compilation unit where it is declared
global scope (non-static declaration outside of a function): the symbol is visible throughout the whole program.
At most, you can hide the declaration in a private include file that you do not declare in the official documented API. That way obedient users should not use it. But you cannot prevent users to put the declaration in their own code and use the function.
Put them in an internal header file that's only used inside the library and not distributed to end users—say, core_internal.h.
I found a neater way to lay out my code building upon Serge's answer that I selected, whose most merit goes to.
The key is to put the "private" functions in headers that are only included in C files, not in header files. This way the "private" symbols are available internally but not to an external caller. In a complete example:
core.h:
void my_public_fn();
core_priv.h:
void my_private_fn();
core.c:
#include <stdio.h>
#include "core.h"
#include "core_priv.h"
void my_private_fn() {
printf("Private function called.\n");
}
void my_public_fn() {
printf("Public function called.\n");
}
module_a.h:
#include "core.h"
void module_a_fn();
module_a.c:
#include "core_priv.h"
#include "module_a.h"
void module_a_fn() {
my_private_fn();
my_public_fn();
}
And if we want, we can group possibly multiple modules in a common library header.
library.h:
#include "module_a.h"
// etc.
This way, a program using the library only needs to include one file with only:
main.c:
#include "library.h"
int main() {
//my_private_fn(); // This triggers a compile warning.
my_public_fn(); // I can still reach the "core" public function.
module_a_fn(); // This calls the "private" function internally.
return 0;
}
Compiling with gcc -Wall *.c -o main.o and executing ./main.o yields:
Public function called.
Private function called.
Public function called.

How can I use a declared but undefined function in C regardless?

So what I want to do is I want to create a kind of framework for myself in the future but I realized I can't do something. It goes like this:
void whenPressedQ();
void whenPressedW();
...
void checkPressQ(){
whenPressedQ();
printf("Q was pressed");
}
...
void whenPressedW(){
doThings();
}
Later I will define these functions and choose which of them to use.
Problem is I can't do this for the other functions if I haven't defined them below. I get an "undefined function" error. Is there any way I can solve this? I've tried using pointers to functions and check if it's null but it's the same thing.
You can pass pointers to callback functions, or wrap them in structures, then have the library pass back a pointer to a function that matches the signature later, even one that you will write in the future. This was how the first C++ compilers implemented virtual methods of objects.
If you just want the code to compile while you’re getting around to the unimplemented functions, you can create dummy stub functions to shut the linker up.
Update
Here are some examples of what I mean. Your question is somewhat ambiguous. If what you are asking is how you can declare functions that you intend to implement later, and still be able to compile the program, the answer is to provide stubs. Here’s a MCVE of your interface:
#include <stdio.h>
#include <stdlib.h>
/* In older versions of C, a declaration like void doThings() would turn
* type-checking of function arguments off, like for printf().
*/
void whenPressedQ(void);
void whenPressedW(void);
void doThings(void); // Added this declaration.
void checkPressQ()
{
whenPressedQ();
printf("Q was pressed.\n"); // Don't forget the newline!
}
void whenPressedW()
{
doThings();
}
// Stub implementations:
void whenPressedQ(void)
// FIXME: Print an error message and abort the program.
{
fflush(stdout); // Don't mix the streams!
fprintf( stderr, "Unimplemented function whenPressedQ() called.\n" );
exit(EXIT_FAILURE);
}
void doThings(void)
// Is nothing a thing?
{}
// Test driver:
int main(void)
{
whenPressedW();
whenPressedQ(); // fails;
// Not reached.
return EXIT_SUCCESS;
}
If you want to let the program dynamically select which function to call, that is more complicated, but you can do it with callbacks. Here’s a simple example.
#include <stdio.h>
#include <stdlib.h>
// This would ordinarily go in a .h file:
typedef const char*(*callback_t)(void); // The type of a callback function.
extern callback_t get_the_answer(void);
// This would ordinarily go in a .c file:
int main(void)
{
callback_t ask_the_question = get_the_answer();
printf( "The answer to life, the Universe and Everything is %s.\n",
ask_the_question()
);
return EXIT_SUCCESS;
}
// This would ordinarily go in another .c file:
static const char* the_answer_is(void)
{
return "42";
}
callback_t get_the_answer(void)
{
return &the_answer_is;
}
The error you are getting a linker error. If you are not trying to build an executable, then you can just compile and do not link. On Linux / OS X, you can pass the -c flag to clang or gcc. On Windows, you can pass the /c flag to cl.exe when compiling.
You can then link the object files directly later, or build a static or dynamic library out of them.

File descriptors in C. Lugging them around vs static global

If I'm writing a library that uses a file descriptor for doing stuff, when should I return it from lib_init() for the higher layer code to use and pass to my lib_do_stuff() calls, and when can I leave it as a private "member" in my C library as a static global in .c file?
If I don't think the user of my library should have control or even access to the file descriptor, can I just leave it, much like in C++ it would just be private?
What are the downsides for doing it either way?
Expanding my suggestion with an example.
Your library needs two (at least) header files: One public that the users of your library includes, and one private that you include only in your library source files.
The public could be something like
#pragma once
// This is all that is needed to declare pointers to the internal structure
typedef struct internal_structure STRUCTURE;
// The public API of your library
STRUCTURE *lib_init(void);
void lib_cleanup(STRUCTURE *s);
...
Then you have the private header file
#pragma once
struct internal_structure
{
int fd;
// Other members as needed
...
};
// Possible function prototypes of private functions
Then in your library source files you include both the public and the private header files, and use STRUCTURE for the black-box structure:
#include <stdlib.h>
#include "public.h"
#include "private.h"
STRUCTURE *lib_init(void)
{
STRUCTURE *s = malloc(sizeof *s);
s->fd = open(...);
// Other initialization
...
return s;
}
void lib_cleanup(STRUCTURE *s)
{
// Other cleanup
...
close(s->fd);
free(s);
}
Then the users of your library includes only the public header file, and uses your well-defined API:
#include "public.h"
int main(void)
{
STRUCTURE *s = lib_init();
...
lib_cleanup(s);
return 0;
}
The public functions should all take STRUCTURE * as one of their arguments, typically their first argument, similar to the lib_cleanup function. The function can then use the structure and its members any way they want.

How to use REAL function once it is declared as WEAK function in C?

I have a problem when using WEAK reference in C. Make assumption, I have the src code structure as follows:
//Eclipse C project structure
drv
| dummy
| | dummy_Test.h
| | dummy_TestWeakAttribute.h
| src
| | source_sample.c
| test
| | myModules
| strong_test_case.c
| weak_test_case.c
test_program.c
And:
//test_program.c
#include "drv/dummy/dummy_TestWeakAttribute.h"
#include "drv/dummy/dummy_Test.h"
int main() {
printf("===================\n");
printf(" Welcome to main \n");
printf("===================\n");
// Expectation
test(); //-->real function
function(); //-->real function
test_function_strong(); //-->real function
test_function_weak(); //-->weak function
return 0;
}
//source_sample.c
#include "../dummy/dummy_TestWeakAttribute.h"
#include "../dummy/dummy_Test.h"
static void test(void) {
printf("NOT overridden!\n");
}
static void function(void){
int a =1;
a++;
test();
}
//dummy_Test.h
#ifndef DRV_DUMMY_DUMMY_TEST_H_
#define DRV_DUMMY_DUMMY_TEST_H_
#define static
//definitions
//struct definitions
//dummy functions
static void test(void);
static void function(void);
//global variable definitions
#endif /* DRV_DUMMY_DUMMY_TEST_H_ */
//dummy_TestWeakAttribute.h
#define static //disable static keyword
static void __attribute__((weak)) test(void);
//weak_test_case.c
#include "../../dummy/dummy_TestWeakAttribute.h"
#include "../../dummy/dummy_Test.h"
static void test(void){
printf("overridden successfully!\n");
}
void test_function_weak(void){
function();
}
//strong_test_case.c
#include "../../dummy/dummy_Test.h"
void test_function_strong(void){
function();
}
I got the result on the screen:
===================
Welcome to main
===================
overridden successfully!
overridden successfully!
overridden successfully!
overridden successfully!
I can't use the REAL function anymore. All my making calls to the real test function is impossible because it was declared as __attribute__((weak)) before. So, Is there anybody having idea on this case ? The main purpose, I'd like to call my real test (in source_sample.c) but don't remove weak attribute as well.
First off, be aware that weak linkage is not a C concept. It is an ELF concept, at least for our purposes, and GCC (and other compiler) support for it is a C extension. Therefore, little of what I have to say is based on the C standard. With that said ...
Your program has two functions test(), both with weak linkage. If there were an alternative with strong linkage then that would override both. Since there is not, it is unspecified which of the two is linked to any given reference (call), but it follows from the mechanism of ELF dynamic linking that the same one would would be linked to every reference in any given dynamic object.
Other than system libraries, you have only one dynamic object in play -- the program -- so it stands to reason that the same implementation of test() is called at every point. It's unclear to me why you suppose it would be otherwise. Note in particular that the weird games you are playing with the static keyword are strictly obfuscatory. You have no actual static declarations anywhere in the code you present.
You indeed could declare a static function test in some file, and in that case you would expect calls to test() from within that file to be linked to the internal static version. To the best of my knowledge, however, a static function cannot also be weak. That wouldn't make any sense.
The main purpose, I'd like to call my real test (in source_sample.c) but don't remove weak attribute as well.
So you want to provide for overriding some references to the function but not others? Are you nuts? What a nightmare that would be to build, and I don't even want to think about maintaining it.
If you want to provide a default implementation that you can always call then you cannot make that the weak function. Doing so is inconsistent with always being able to call it. You can, however, make it a separate, ordinary function that the weak one calls, and any other function also can call:
test.h:
#ifndef TEST_H
#define TEST_H
void test(void) __attribute__((weak));
void test_default(void);
#endif
test.c:
#include "test.h"
void test_default(void) {
printf("I am the default implementation");
}
void test(void) {
test_default();
}
Anyone with access to test_default() can then call it, but whether it gets called as a result of calling test() depends on what version of test() is linked to the call -- it is weak, so a different version could be provided.
Note also that depending on the scope you want test_default() to have, it might be both possible and sensible to make it static, whereas test() must not be static as long as it is weak.

How to prevent internal structs from being visible to the user of the API?

api.h
The following API is assumed to be distributed as a shared library.
#include "apiInternal.h"
internalStruct* API_init();
extern void API_set_member1(internalStruct* apiStruct, int value);
extern void API_set_member2(internalStruct* apiStruct, int value);
apiInternal.h
typedef struct internalStruct {
int member1;
int member2;
} internalStruct;
sample.c
The program sample.c uses api.h and links with the shared library to use the API.
#include "api.h"
int main()
{
internalStruct *myVar = API_init();
API_set_member1(myVar, 5);
API_set_member2(myVar, 6);
}
The dilemma here is,
Should the api.h that the API implementation uses be different than
the api.h distributed to the users of the API? If so, how can I do
this without including apiInternal.h?
Is there a better way to do/design this?
You can build sample.c without including apiInternal.h and the structure definition.
Within api.h drop the #include "apiInternal.h". Instead, declare the structure, this is called a forward declaration, (easiest to drop the typdef) so api.h will look like:
struct internalStruct;
struct internalStruct* API_init();
extern void API_set_member1(struct internalStruct* apiStruct, int value);
extern void API_set_member2(struct internalStruct* apiStruct, int value);
This works because the compiler can build sample.c as it only needs to know the size of the pointer rather than the complete structure declaration. You then only need to include apiInternal.h within your library code. You won't need to distribute apiInternal.h to your users.
If you library code has multiple files, then you will need apiInternalh.h. Each of you library source files will include apiInternal.h. If you library code is a single file, then I typically just define the structure at the top of the library C file, the extra header is not necessary.
This is called an opaque pointer. The Wikipedia article provides an additional example. This is nice way of achieving information-hiding from within C.

Resources