user3758232
user3758232

Reputation: 862

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?

Upvotes: 2

Views: 670

Answers (3)

user3758232
user3758232

Reputation: 862

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.

Upvotes: 0

Serge Ballesta
Serge Ballesta

Reputation: 148965

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.

Upvotes: 3

John Kugelman
John Kugelman

Reputation: 361635

Put them in an internal header file that's only used inside the library and not distributed to end users—say, core_internal.h.

Upvotes: 2

Related Questions