Two versions of same function: inline and normal? - c

I'd like to inline some functions, however, they are shared across the team and I don't want to force people to use them.
What would be the best way to add inline versions?
// normal
int func1();
int func2();
// inline versions
inline int inl_func1() { ... }
inline int inl_func2() { ... }
Would something like that make sense?
Edit:
Ideally:
I wouldn't have to write the same function definitions (function body) twice.
It would all be handled with s single define.

Declare/define the inline version and declare the non-inline version in the header file with different names.
// "func.h"
// normal
int func1(void);
int func2(void);
// inline versions
static inline int func1_inline(void) { ... }
static inline int func2_inline(void) { ... }
This allows a user to use either form or both. There is little compelling reason to use the same name and only allow one form.
Both can be handy for code that needs speed vs. space on some calls and not others.
This has a benefit that the one .c file that defines/implements func1(), func2() can use simple code to insure equivalent functionality.
#include "func.h"
int func1(void) {
return func1_inline();
}
int func2(void) {
return func2_inline();
}
BTW, declaring a function like int func1(); does not mean the same as int func1(void);. int func1(); means func1 returns an int, but provids no information about what can be passed to it. It is more like pseudo-code int func1(...);

Perhaps you could tell the people who want the inline functions to define a specific macro before including your header file:
#define WANT_INLINE_FUNC1
#include "awesome_funcs.h"
People who want the to call the externally linked function should omit the macro:
#include "awesome_funcs.h"
Then, in "awesome_funcs.h":
#ifdef WANT_INLINE_FUNC1
inline int func1(int param)
{
/* function body here */
}
#else
extern int func1(int param);
#endif
You also need to define a copy of the function with external linkage in one of your library files, e.g. in "awesome_funcs.c":
#define WANT_INLINE_FUNC1
#include "awesome_funcs.h"
/*
* This will define func1 with external linkage,
* but the function body is copied from the inline definition
* in "awesome_funcs.h".
*/
extern int func1(int param);
EDIT 1
You could combine this with chux's answer and get the best of both worlds (unless that makes things too confusing for your users). Just replace func1 in "awesome_funcs.h" with the following:
static inline int inl_func1(int param)
{
/* function body here */
}
#ifdef WANT_INLINE_FUNC1
inline int func1(int param)
{
return inl_func1(param);
}
#else
extern int func1(int param);
#endif
Then inl_func1 will always be the inline version, and func1 may or may not be inline, depending on whether or not the WANT_INLINE_FUNC1 macro was defined before including "awesome_funcs.h".

What would be the best way to add inline versions?
Your easiest course of action would be to declare static inline versions of these functions:
static inline int func1() { ... }
static inline int func3() { ... }
The function names do not need to differ from those of the corresponding external functions. However, if you #include a header that has declarations of functions with those names, then they must be compatible, AND there must be prior static declarations. For example:
static inline int func1(/* params */);
static inline int func3(/* params */);
#include "our_functions.h"
// ...
static inline int func1(/* params */) {
// implementation ...
}
static inline int func3(/* params */) {
// implementation ...
}
This will allow you to add inline versions without modifying your existing code that calls the external versions of these functions, and without affecting any other translation units. There is at least one alternative, but I don't see anything to recommend it over the above for your particular circumstances.

Related

C - Should Function Implementations in Header use extern/inline/static?

I am using function implementations in a header file for simple code sharing. Minimal example:
foo.h:
#ifndef FOO_H
#define FOO_H
// potentially want to include extern/static/inline keyword for this function
int max(int x, int y) {
return x < y ? y : x;
}
#endif
bar.c:
#include <stdio.h>
#include "foo.h"
int main() {
printf("Max of 1 and 2: %d", max(1, 2));
}
I was suggested to the inline keyword for the functions implemented in the .h file. However, that gives me a linker error. If I use extern inline it does compile, but since I just guessed to try this I am not confident that it isn't dangerous/bad in some way.
Is using extern inline appropriate here? If not, what combination of static, extern, and inline should I use?
If you're going to put the implementation of a function in a header file, it must have the static storage class specifier. This restricts the visibility of the function name to only the translation unit (i.e. .c file) where it is ultimately built-in. Note that doing so means that if multiple source files include this header then each one will have its own copy of the function.
Using inline as well as static is not necessary, but it can serve as a hint to the compiler to perform certain optimizations on it.

Can GCC ignore static declaration of a function?

In my application I have a build config for pseudo unit testing (this is more a kind of manual debugging a dedicated function).
In those unit tests I'd like to access functions declared as static in their translation unit.
Is there an option of GCC that would allow me to call static functions from anywhere?
I'd like to avoid:
#if UNIT_TEST_MODE
void myfunction(void)
#else
static void myfunction(void)
#end
{
// body
}
Everywhere!
Thanks for your help :).
There is not need to be verbose. Use a prefix define for every static function:
#if UNIT_TEST_MODE
#define UNIT_TEST_STATIC
#else
#define UNIT_TEST_STATIC static
#end
UNIT_TEST_STATIC void myfunction(void)
{
// body
}
Another option is to move all static function from that .c file to a separate header. That header is included only in that .c file, but it can be included in the unit test .c file if needed. The functions will remain invisible in other files, unless the header is manually included.
(They will have to be defined as static inline. )
As applied to a function or file-scope variable, the static keyword means that the declared function or object has internal linkage. That means such a function or object can be directly referenced only from within the same translation unit. GCC has no option to alter this core provision of the C language, nor should it have.
Your alternatives, then, are either
to give the functions in question external linkage instead of internal linkage, perhaps conditionally, or
to make them available to the test code via an indirect mechanism, such as function pointers initialized and provided to the test code by some facility (another function, a global variable) inside the translation unit.
The first alternative is simpler, but using it means that the code under test is not wholly equivalent to code built for ordinary use. Additionally, this option is not viable if the names of any of the erstwhile-static functions collide with the names of other global objects. This option has been adequately demonstrated in other answers, so I won't go into further detail here.
The pros and cons of the second alternative are more or less the mirror image of those of the first. It is more complicated, but the functions can be tested in the same form that they have in the production build, and you can avoid name collisions by this route. There are many possible variations on this approach; here's one:
test_header.h
#ifndef TEST_HEADER_H
#define TEST_HEADER_H
struct test_pointers {
int (*function_to_test)(const char *);
};
void initialize_test_pointers(struct test_pointers *pointers);
#endif
module_under_test.c
static int function_to_test(const char *);
#ifdef ENABLE_TESTING
#include "test_header.h"
extern void initialize_test_pointers(struct test_pointers *pointers) {
pointers->function_to_test = function_to_test;
}
#endif
static int function_to_test(const char *s) {
// ... whatever
}
the_test.c
#include "test_header.h"
int test_it(void) {
struct test_pointers pointers;
char test_input[] = "test THIS!";
const int expected_result = 42;
int result;
initialize_test_pointers(&pointers);
result = pointers.function_to_test(test_input);
return result == expected_result;
}
No, it can not. This keyword specifies visibility of a function to be translation-unit only, as defined by launguage standard. Ignoring it by a compiler would render it non-conformant.
UPD. To solve your problem, you can indeed do the preprocessor directive trick, as mentioned in comments to your question.
This does not answer your question about GCC, but as a solution to your unit testing problem, you could conditionally compile a wrapper function in the same module,
static void myfunction(void)
{
// body
}
#if UNIT_TEST_MODE
void myfunction_test(void)
{
myfunction();
}
#endif
Or, you could #include the module from a unit test wrapper file,
// unit_test.c
#include "myfunction.c"
void unit_test()
{
myfunction();
}

How to enforce an API definition with macros or some other mechanism?

I have a C header file as part of an API that I am developing which exposes a number of functions. For example:
api.h
void foo();
int bar(char * foobar);
Now, most functions that I expose are actually defined within the API, however, there are some that I leave to the using-developer to implement herself. To make it easier for the developer and enforce conformance to my API I added the following macros:
api.h(modified)
#define DEFINE_FOO() \
void foo()
void foo();
#define DEFINE_BAR() \
int bar(char * foobar)
int bar(char * foobar);
to be used as follows:
implement.c
#include "api.h"
DEFINE_FOO() {
// Codez
}
DEFINE_BAR() {
// More codez
}
One of the things that bothers me about this approach is that the developer will use the DEFINE_* macros but not necessarily intuit that a function, namely "bar" takes arguments. Is there a way to improve this approach or is there a better approach to enforcing custom API definitions in C? Thanks!
There's really no need to use macros and I'd recommend against it (and I've done plenty of "crazy" things with macros over the [last 35+] years).
If you're defining the API, this implies that you're putting [ANSI] prototypes in api.h for all your functions. That doesn't mean you will implement them--it only means that you define the architecture/API. Any function that doesn't have a prototype in api.h isn't part of the API [obviously].
If you do that, the compiler will flag any mismatches. Simply require that the developer include the api.h at the top.
Here's an api.h:
void foo(void);
int bar(char *foobar);
A well conforming .c will compile cleanly:
#include "api.h"
#include <stdio.h>
void
foo(void)
{
}
int
bar(char *str)
{
return 0;
}
A non-conformant .c will not compile correctly:
#include "api.h"
#include <stdio.h>
void
foo(int x)
{
printf("foo: %d\n",x);
}
int
bar(char *str)
{
return 0;
}
You'll get compilation errors:
bad.c:5:1: error: conflicting types for ‘foo’
foo(int x)
^
In file included from bad.c:1:0:
api.h:2:6: note: previous declaration of ‘foo’ was here
void foo(void);
^
So, if a developer makes a mistake, the ordinary code definitions will handle it.
I wouldn't really recommend your approach, but you can technically make it work.
You can pass arguments into macros as such:
#define DEFINE_BAR(arg) \
int bar(char* arg)
Now the programmer can call
DEFINE_BAR(arg_name) {
return strlen(arg_name);
}
This will be turned into the following by cpp:
int bar(char* arg_name) {
return strlen(arg_name);
}

Declare function as non-static and implement as static inline

I want to write different implementations for my function, some inline and some not. Thus, I want to declare the function as:
// MyHeader.h
int myFunc(void);
#if DO_INLINE
static inline int myFunc(void) { return 42; }
#endif
And then also have:
// MySource.c
#if !DO_INLINE
#include "myHeader.h"
int myFunc(void) { return 42; }
#endif
I'll specify DO_INLINE at compile time.
MSVC has no problems with this, but GCC (4.1.1) complains that I'm declaring a static function after I've already declared it as non-static. If I remove the static qualifier, and #include "MyHeader.h" from more than one compilation unit, it will complain about multiple definitions. (As if the inline functions are extern.) I don't quite understand why the compiler has problems with this.
I think this should be pretty obvious and unambiguous:
int myFunc(void);
static inline int myFunc(void) { return 42; }
It shouldn't require the declaration to be static.
That said, there is a solution to my problem that I'm trying very hard to avoid:
#if DO_INLINE
#define MAYBE_STATIC static
#else
#define MAYBE_STATIC
#endif
MAYBE_STATIC int myFunc(void);
EDIT: Here is a more realistic use case for this: http://codepad.org/OkC0Su3v
This header.h should work:
// MyHeader.h
#if DO_INLINE
static inline int myFunc(void) { return 42; }
#else
int myFunc(void);
#endif
Figured it out closely enough. The implementation should be defined as "extern inline" instead:
// MyHeader.h
int myFunc(void);
#if DO_INLINE
extern inline int myFunc(void) { return 42; }
#endif
The compiler will inline this function where it sees fit, but still compile it once as a function, to make it available for linking. That part I don't need, but it doesn't really hurt.

Inlined Setter and Getter functions in C

In C++ I can have a getter function declared inline in a header file:
class Cpp_Example
{
public:
unsigned int get_value(void)
{ return value;}
private:
unsigned int value;
};
By including this header file, client methods and functions can use the getter function to access a private variable.
I'm looking to model this concept in the C language:
hello.h:
#ifndef HELLO_H
#define HELLO_H
#include <stdio.h>
inline void Print_Hello(void)
{
extern const char hello_text[32];
puts(hello_text);
}
inline void Print_Value(void)
{
extern unsigned int value;
printf("Value is: %d\n", value);
}
#endif // HELLO_H
hello.c:
const char hello_text[32] = "Hello World!\n";
static unsigned int value = 5U;
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "hello.h"
int main(void)
{
Print_Hello();
Print_Value();
// puts(hello_text);
return EXIT_SUCCESS;
}
I get a linker error from gcc:
$ gcc -o main.exe main.c hello.c
/tmp/cc41ZB8H.o:main.c:(.rdata$.refptr.value[.refptr.value]+0x0): undefined reference to `value'
collect2: error: ld returned 1 exit status
Is there a way to have an inline function (in a header file) access a static variable in another translation unit?
Or is there a way to implement an inlined getter function?
I'm using IAR Embedded Workbench, ARM7TDMI processor on an embedded platform.
The gcc compiler is used to testing concepts on the PC.
Edit 1: Background
I'm looking to optimize getter calls that are inside a critical section. The objective is to reduce the time spent in the critical section.
Edit 2: No Globals
The Coding Guidelines our shop uses states no global variables.
Also, this system is an RTOS running MicroCOSII.
First of all, the same way you have private variables in C++, you probably mean to have private variables for a struct rather than global. With that assumption, here's one model you can use:
/* some_type.h */
struct some_type
{
int public_data;
void *privates;
};
struct some_type_privates
{
char hello[32];
int value;
};
inline const char *get_hello(struct some_type *t)
{
struct some_type_privates *p = t->privates;
return p->hello;
}
inline int get_value(struct some_type *t)
{
struct some_type_privates *p = t->privates;
return p->value;
}
/* similarly for setters */
The same way that your private variables and their getters and setters are in the header file, you can do it in C, too.
On the side, I'd like to recommend not to try coding C++ in C. While C++ likes to complicate things a lot to prevent the idiot from breaking something, C on the other hand trusts the programmer has some degree of intelligence. Whether these assumptions are justified are not the matter of discussion. But what I mean to say is that the spirit of C is not to hide a variable so that the programmer doesn't mistakenly access it.
That said, this is how you would normally make a struct in C:
struct some_type
{
int public_data;
char hello[32]; /* read only */
/* internal */
int value;
};
(with enough documentation of course) which tells any programmer that she shouldn't write over hello but can freely read it (what you were trying to achieve by an inline getter). It also tells that value is private so the programmer shouldn't read or write it.
You can see this in many POSIX functions that take or return a struct. Some that don't need to control the access let you freely modify the struct, such as stat. Some that do need to check the input have setters, such as pthread_attr_*.
You need to remove the static keyword. static definitions are local to the compilation unit.
As Shabbas wrote, it doesn't really work that way in C.
The keyword inline implies static, even if the compilers doesn't actually inline it. If it is such a short function, it will probably inline it. But the point is, if it would not be static, it could not even consider inlineing it, as the function would need to be visible externally, it would need an address, which an inlined function doesn't have.
Since it is local in your compilation unit, it can only work on stuff known inside that compilation unit. Thus you need to say something about that value variable, much like you do need to mention it in the C++ header as well, only in C there is no such thing as private .
You can not have Inlineing and data hiding in the same case, neither in C, nor in C++.
Assuming you mean for global, statically-allocated variables you can do this:
In Example.h:
#ifndef Example
#define Example
extern int getValue();
#endif
In Example.c
#include "Example.h"
static int value;
inline int getValue() {
return value;
}
// All the functions in Example.c have read/write access
In UsesValueExample.c
#include "Example.h"
// All the functions in UsesValueExample.c have read-only access
void printValue() {
printf("value = %d", getValue());
}
If you want to get fancy and force all code to access through a getter and setter, e.g. if the variable is volatile and you want to heavily encourage all the methods to use a local cache of the variable to avoid the overhead of accessing the volatile, then:
In VolatileExample.h:
#ifndef VolatileExample
#define VolatileExample
extern int getValue();
#endif
In VolatileExample.c
#include "VolatileExample.h"
void setValue(); // Forward declaration to give write access
// All the functions in VolatileExample.c have read/write access via getters and setters
void addToValuesAndIncrementValue(int const values[], int const numValues) {
int value = getValue(); // Cache a local copy for fast access
// Do stuff with value
for (int i = 0; i < numValues; i++) {
values[i] += value;
}
value++;
// Write the cache out if it has changed
setValue(value);
}
// Put the definitions after the other functions so that direct access is denied
static volatile int value;
inline int getValue() {
return value;
}
inline void setValue(int const newValue) {
value = newValue;
}
In UsesVolatileValueExample.c
#include "VolatileExample.h"
// All the functions in UsesVolatileValueExample.c have read-only access
void printValue() {
printf("value = %d", getValue());
}
Here is a pattern I've been using to hide global variables.
Inside some header file, such as module_prefix.h, you declare the following:
typedef int value_t; // Type of the variable
static inline value_t get_name(void) __attribute__((always_inline));
static inline void set_name(value_t) __attribute__((always_inline));
static inline value_t get_name(void) {
extern value_t module_prefix_name;
return module_prefix_name;
}
static inline void set_name(value_t new_value) {
extern value_t module_prefix_name;
module_prefix_name = new_value;
}
/* Note that module_prefix_name is *no longer* in scope here. */
Then of course you have to define module_prefix_name in some compilation unit, without the static keyword, as discussed above, e.g. in module_prefix.c you have the following:
#include "module_prefix.h"
value_t module_prefix_name = MODULE_PREFIX_NAME_INIT_VALUE;
This is essentially the same pattern that Thomas Matthews tried to use, drilling down to the essence and making sure that the compiler inlines the functions always and does not unnecessarily generate explicit function bodies. Note the use of module_prefix as poor man's name spaces.

Resources