How could I make a constant in C except using a number - c

I am working on a C math library, and it is using macros do to the most of it's work, I am now facing a problem.
This is what the macro looks like:
the_macro(a, b, c)
and the macro itself does something like:
(a - b > 0) ? error_function : 1
the error_function is used to stop the user at complie time, so if (a - b > 0) is true, then the macro will expand as a function which does not have a definition. So this will cause a linkage error.
Everthing seems good, but today my boss told me we need to do some unit-test, so I wrote a function which wraps the macro:
int my_func(int a, int b, int c)
{
return the_macro(a, b, c);
}
here comes the problem, the code can't pass linkage, because if I use a var instead of a constant to call the_macro, these error_functions will be in the .o file, because the int a, int b, int c are all known at runtime, so I can only call the macro function with constants: the_macro(2, 3, 4) is there any way to avoid this? or is there a better solution to do unit-test on this macro?
EDIT:
The code I'm working on is confidential... but I made an example which demonstrates the problem:
#include <stdio.h>
#define the_macro(a, b)\
(a > b)?error_function():1
// Comment out my_func(), then the program will run normaly
// But if you don't comment it out, the linkage error will come out.
void my_func(int a, int b)
{
the_macro(a, b);
}
int main()
{
printf("%d\n", the_macro(1, 10));
return 0;
}
I'm using gcc-4

Regardless of where you use the macro, if error_function is not declared, you should get a compiler error. If it is declared but not defined, you have undefined behavior. Whether the arguments to the macro are constants or not changes nothing in this respect. (It may affect what the actual behavior is in the case of undefined behavior.)

When you call the macro with constants, the compiler knows the value and thus, perhaps as as optimization, the expression the_macro (5, 4, 0) gets replaced by 1 instead of error_function. When your expression a-b evaluates to <= 0, your compiler replaces it with error_function, and stops your compilation.
On the other hand, when you use variables, the compiler doesn't know the result of the expression and has to use the full expansion of the macro, which contains a call to undefined function, and hence you get the linkage error.

For the purposes of your unit tests (only) why not define error_function() as part of your unit test and have it return an error unconditionally that your test framework can detect. That way you should be able to mimic the behaviour you're seeing at compile time using either constants or variables.
It's not exactly what you want, but unit test frameworks are always, by their nature run-time testing mechanisms, so an automated compile time test is probably not going to be possible.
Alternatively, you could use system() to run a command line build including your library, redirect the output, including errors into a file. You could then open the file and scan for known text of the linkage error.

Let's see if I understand this correctly:
You want a way to break compilation if a-b>0? This is actually impossible unless you use C11. There simply is no way to have the compiler abort depending on a condition. In your case you are trying to use a combination of the optimizer and the linker to get the desired behavior. But this cannot work reliably.
The expression (a - b > 0) ? error_function : 1 may be reduced by the optimizer to one if a-b>0, but this is not guaranteed. There is a guaranteed behavior compiler has to show defined by the C standard and this standard does not mention an optimizer. The same optimizer may sometimes reduce the expression, and sometimes not reduce it depending on other things in your code. Or it may or may not reduce it depending on the command line flags you are passing.
So with using this macro you are writing code, which may suddenly break unexpectedly when you switch compiler, compiler version, operating system, add or remove linked libraries or target architecture. Code that suddenly breaks depending on such changes is very bad. Don't do this to your fellow developers.
Better to write portable code for which you can be sure that future compilers will understand it because it follows the standard. In pre C11 there is no way to do this. If you really need this, tell your boss the only way is to use C11 which has a static_assert keyword which can give you the conditional abortion of the compilation.

Related

gcc builtin function and custom function both invoked in same program

I'm trying to understand when gcc's builtin functions are used. In the following code, both gcc's sqrt() and my custom sqrt() are invoked when I compile without -fno-builtin. Can someone explain what is going on?
Also, I know the list of gcc's builtin functions is at https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html and realize the recommended way around these types of problems is to just rename the conflicting function. Is there a gcc output option/warning that will show when a custom function is named the same as a builtin or when a builtin is used instead of the custom function?
#include <stdio.h>
double sqrt(double);
int main(void)
{
double n;
n = 2.0;
printf("%f\n", sqrt(n));
printf("%f\n", sqrt(2.0));
return 0;
}
double sqrt(double x)
{
printf("my_sqrt ");
return x;
}
running after compiling with gcc -o my_sqrt my_sqrt.c the output is:
my_sqrt 2.000000
1.414214
running after compiling with gcc -fno-builtin -o my_sqrt my_sqrt.c the output is:
my_sqrt 2.000000
my_sqrt 2.000000
It's not the case that two different sqrt functions are called at runtime. The call to sqrt(2.0) happens at compile time, which is legal because 2.0 is a constant and sqrt is a standard library function, so the compiler knows its semantics. And the compiler is allowed to assume that you are not breaking the rules. We'll get around to what that means in a minute.
At runtime, there is no guarantee that your sqrt function will be called for sqrt(n), but it might be. GCC uses your sqrt function, unless you declare n to be const double; Clang goes ahead and does the computation at compile time because it can figure out what n contains at that point is known. Both of them will use the built-in sqrt function (unless you specify -fno-builtin) for an expression whose value cannot be known at compile-time. But that doesn't necessarily mean that they will issue code to call a function; if the machine has a reliable SQRT opcode, the compiler could choose to just emit it rather than emitting a function call.
The C standard gives compilers a lot of latitude here, because it only requires the observable behaviour of a program to be consistent with the results specified by the semantics in the standard, and furthermore it only requires that to be the case if the program does not exhibit undefined behaviour. So the compiler is basically free to do any computation it wants at compile-time, provided that a program without undefined behaviour would produce the same result. [Note 1].
Moreover, the definition of "the same result" is also a bit loose for floating point computations, because the standard semantics do not prevent computations from being done with more precision than the data types can theoretically represent. That may seem innocuous, but in some cases a computation with extra precision can produce a different result after rounding. So if during compilation a compiler can compute a more accurate intermediate result than would result from the code it would have generated for run-time computation of the same expression, that's fine as far as the standard is concerned. (And most of the time, it will be fine for you, too. But there are exceptions.)
To return to the main point, it still seems surprising that the compiler, which knows that you have redefined the sqrt function, can still use the built-in sqrt function in its compile-time computation. The reason is simple (although often ignored): your program is not valid. It exhibits undefined behaviour, and when your program has undefined behaviour, all bets are off.
The undefined behaviour is specified in §7.1.3 of the standard, which concerns Reserved Identifiers. It supplies a list of reserved identifiers, which really are reserved, whether the compiler you happen to be using warns you about that or not. The list includes the following, which I'll quote in full:
All identifiers with external linkage in any of the following subclauses (including the future library directions) and errno are always reserved for use as identifiers with external linkage.
The "following subclauses" at point contain the list of standard library functions, all of which have external linkage. Just to nail the point home, the standard continues with:
If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), the behavior is undefined. [Note 2]
You have declared sqrt as an externally-visible function, and that's not permitted whether or not you include math.h. So you're in undefined behaviour territory, and the compiler is perfectly entitled to not worry about your definition of the sqrt function when it is doing compile-time computation. [Note 3]
(You could try to declare your sqrt implementation as static in order to avoid the restriction on externally-visible names. That will work with recent versions of GCC; it allows the static declaration to override the standard library definition. Clang, which is more aggressive about compile-time computations, still uses the standard definition of sqrt. And a quick test with MSVC (on godbolt.org) seems to indicate that it just outright bans redefinition of the standard library function.)
So what if you really really want to write sqrt(x) for your own definition of sqrt? The standard does give you an out: since sqrt is not reserved for macro names, you can define it as a macro which is substituted by the name of your implementation [Note 4], at least if you don't #include <math.h>. If you do include the header, then this is probably not conformant, because in that case the identifiers are reserved as well for macro names [Note 5].
Notes
That liberty is not extended to integer constant expressions, with the result that a compiler cannot turn strlen("Hello") into the constant value 5 in a context where an integer constant expression is required. So this is not legal:
switch (i) {
case strlen("Hello"):
puts("world");
break;
default: break;
}
But this will probably not call strlen six times (although you shouldn't count on that optimisation, either):
/* Please don't do this. Calling strlen on every loop iteration
* blows up linear-time loops into quadratic time monsters, which is
* an open invitation for someone to do a denial-of-service attackç
* against you by supplying a very long string.
*/
for (int i = 0; i < strlen("Hello"); ++i) {
putchar("world"[i]);
}
Up to the current C standard, this statement was paragraph 2 of §7.1.3. In the C23 draft, though, it has been moved to paragraph 8 of §6.4.2.1 (the lexical rules for identifiers). There are some other changes to the restrictions on reserved identifiers (and a large number of new reserved identifiers), but that doesn't make any difference in this particular case.
In many instances of undefined behaviour, the intent is simply to let the compiler avoid doing extra sanity checks. Instead, it can just assume that you didn't break the rules, and do whatever it would otherwise do.
Please don't use the name _sqrt, even though it will probably work. Names starting with underscores are all reserved, by the same §7.1.3. If the name starts with two underscores or an underscore followed by a capital letter, it is reserved for all uses. Other identifiers starting with an underscore are reserved for use at file scope (both as a function name and as a struct tag). So don't do that. If you want to use underscores to indicate that the name is somehow internal to your code, put it at the end of the indentifier rather than at the beginning.
Standard headers may also define the names of standard library functions as function-like macros, possibly in order to substitute a different reserved name, known to the compiler, which causes the generation of inline code, perhaps using special-purpose machine opcodes. Regardless, the standard requires that the functions exist, and it allows you to #undef the macros in order to guarantee that the actual function will be used. But it doesn't explicitly allow the names to be redefined.

Unit Testing a Function Macro

I'm writing unit tests for some function macros, which are just wrappers around some function calls, with a little housekeeping thrown in.
I've been writing tests all morning and I'm starting to get tedium of the brainpan, so this might just be a case of tunnel vision, but:
Is there a valid case to be made for unit testing for macro expansion? By that I mean checking that the correct function behavior is produced for the various source code forms of the function macro's arguments. For example, function arguments can take the form, in source code of a:
literal
variable
operator expression
struct member access
pointer-to-struct member access
pointer dereference
array index
function call
macro expansion
(feel free to point out any that I've missed)
If the macro doesn't expand properly, then the code usually won't even compile. So then, is there even any sensible point in a different unit test if the argument was a float literal or a float variable, or the result of a function call?
Should the expansion be part of the unit test?
As I noted in a comment:
Using expressions such as value & 1 could reveal that the macros are careless, but code inspections can do that too.
I think going through the full panoply of tests is overkill; the tedium is giving you a relevant warning.
There is an additional mode of checking that might be relevant, namely side-effects such as: x++ + ++y as an argument. If the argument to the macro is evaluated more than once, the side-effects will probably be scrambled, or at least repeated. An I/O function (getchar(), or printf("Hello World\n")) as the argument might also reveal mismanagement of arguments.
It also depends in part on the rules you want to apply to the macros. However, if they're supposed to look like and behave like function calls, they should only evaluate arguments once (but they should evaluate each argument — if the macro doesn't evaluate an argument at all, then the side-effects won't occur that should occur (that would occur if the macro was really a function).
Also, don't underestimate the value of inline functions.
Based on the comments and some of the points made in #Jonathan Leffler's answer, I've come to the conclusion that this is something that is better tested in functional testing, preferably with a fuzz tester.
That way, using a couple of automation scripts, the fuzzer can throw a jillion arguments at the function macro and log those that either don't compile, produce compiler warnings, or compile and run, but produce the incorrect result.
Since fuzz tests aren't supposed to run quickly (like unit tests), there's no problem just adding it to the fuzz suite and letting it run over the weekend.
The goal of testing is to find errors. And, your macro definitions can contain errors. Therefore, there is a case for testing macros in general, and unit-testing in particular can find many specific errors, as will be explained below.
Code inspection can obviously also be used to find errors, however, there are good points in favor of doing both: Unit-tests can cheaply be repeated whenever the respective code is modified, say, for reactoring.
Code inspections can not cheaply be repeated (at least they cause more effort than re-running unit-tests), but they also can find other points that tests can never detect, like, wrong or bad documentation, design issues like code duplication etc.
That said, there are a number of issues you can find when unit-testing macros, some of which were already mentioned. And, it may in principle be possible that there are fuzz testers which also check for such problems, but I doubt that problems with macro definitions are already in focus of fuzz-testers:
wrong algorithm: Expressions and statements in macro definitions can just be as wrong as they can be in normal non-macro code.
unsufficient parenthesization (as mentioned in the comments): This is a potential problem with macros, and it can be detected, possibly even at compile time, by passing expressions with operators with low precedence as macro arguments. For example, calling FOO(x = 2) in test code will lead to a compile error if FOO(a) is defined as (2 * a) instead of (2 * (a)).
unintended multiple use of arguments in the expansion (as mentioned by Jonathan): This also is a potential problem specific to macros. It should be part of the specification of a macro how often its arguments will be evaluated in the expanded code (and sometimes there can no fixed number be given, see assert). Such statements about how often an argument will be evaluated can be tested by passing macro arguments with side effects that can afterwards be checked by the test code. For example, if FOO(a) is defined to be ((a) * (a)), then the call FOO(++x) will result in x being incremented twice rather than once.
unintended expansion: Sometimes a macro shall expand in a way that causes no code to be produced. assert with NDEBUG is an example here, which shall expand such that the expanded code will be optimized away completely. Whether a macro shall expand in such a way typically depends on configuration macros. To check that a macro actually 'disappears' for the respective configuration, syntactically wrong macro arguments can be used: FOO(++ ++) for example can be a compile-time test to see if instead of the empty expansion one of the non-empty expansions was used (whether this works, however, depends on whether the non-empty expansions use the argument).
bad semicolon: to ensure that a function like macro expands cleanly into a compound statement (with proper do-while(0) wrapper but without trailing semicolon), a compile time check like if (0) FOO(42); else .. can be used.
Note: Those tests I mentioned to be compile-time tests are, strictly speaking, just some form of static analysis. In contrast to using a static analysis tool, such tests have the benefit to specifically test those properties that the macros are expected to have according to their design. Like, static analysis tools typically issue warnings when macro arguments are used without parentheses in the expansion - however, in many expansions parentheses are intentionally not used.

initialising constant static array with algorhythm [duplicate]

I am thinking about the following problem: I want to program a microcontroller (let's say an AVR mega type) with a program that uses some sort of look-up tables.
The first attempt would be to locate the table in a separate file and create it using any other scripting language/program/.... In this case there is quite some effort in creating the necessary source files for C.
My thought was now to use the preprocessor and compiler to handle things. I tried to implement this with a table of sine values (just as an example):
#include <avr/io.h>
#include <math.h>
#define S1(i,n) ((uint8_t) sin(M_PI*(i)/n*255))
#define S4(i,n) S1(i,n), S1(i+1,n), S1(i+2,n), S1(i+3,n)
uint8_t lut[] = {S4(0,4)};
void main()
{
uint8_t val, i;
for(i=0; i<4; i++)
{
val = lut[i];
}
}
If I compile this code I get warnings about the sin function. Further in the assembly there is nothing in the section .data. If I just remove the sin in the third line I get the data in the assembly. Clearly all information are available at compile time.
Can you tell me if there is a way to achieve what I intent: The compiler calculates as many values as offline possible? Or is the best way to go using an external script/program/... to calculate the table entries and add these to a separate file that will just be #included?
The general problem here is that sin call makes this initialization de facto illegal, according to rules of C language, as it's not constant expression per se and you're initializing array of static storage duration, which requires that. This also explains why your array is not in .data section.
C11 (N1570) §6.6/2,3 Constant expressions (emphasis mine)
A constant expression can be evaluated during translation rather than
runtime, and accordingly may be used in any place that a constant may
be.
Constant expressions shall not contain assignment, increment,
decrement, function-call, or comma operators, except when they are
contained within a subexpression that is not evaluated.115)
However as by #ShafikYaghmour's comment GCC will replace sin function call with its built-in counterpart (unless -fno-builtin option is present), that is likely to be treated as constant expression. According to 6.57 Other Built-in Functions Provided by GCC:
GCC includes built-in versions of many of the functions in the
standard C library. The versions prefixed with __builtin_ are always
treated as having the same meaning as the C library function even if
you specify the -fno-builtin option.
What you are trying is not part of the C language. In situations like this, I have written code following this pattern:
#if GENERATE_SOURCECODE
int main (void)
{
... Code that uses printf to write C code to stdout
}
#else
// Source code generated by the code above
... Here I paste in what the code above generated
// The rest of the program
#endif
Every time you need to change it, you run the code with GENERATE_SOURCECODE defined, and paste in the output. Works well if your code is self contained and the generated output only ever changes if the code generating it changes.
First of all, it should go without saying that you should evaluate (probably by experiment) whether this is worth doing. Your lookup table is going to increase your data size and programmer effort, but may or may not provide a runtime speed increase that you need.
If you still want to do it, I don't think the C preprocessor can do it straightforwardly, because it has no facilities for iteration or recursion.
The most robust way to go about this would be to write a program in C or some other language to print out C source for the table, and then include that file in your program using the preprocessor. If you are using a tool like make, you can create a rule to generate the table file and have your .c file depend on that file.
On the other hand, if you are sure you are never going to change this table, you could write a program to generate it once and just paste it in.

When did/does using #define to define a static function in C work?

Working in a new to me code base and I have come across some C code that looks like this:
static int* functionA(int* anInt);
#define functionA(anInt) ( <a 1 line '? :' function>)
Maybe this is obvious to people who’s C coding is a bit more fresh in their head than mine, but it looks a little odd to me. The compiler seems to agree as it spits out a message stating
error: ‘functionA’ declared ‘static’ but never defined.
(I am using gcc 4.8.2.)
As this is has turned up in some library code that we are evaluating I assume that for some compilers, some of the time, this is valid. Please could someone help explain when it is valid?
My best guess is this some old fashioned way of doing inline static function definitions. However there is every chance I am missing something subtle. An explanation of what is being achieved would also be helpful but really I want to know when this code is valid.
As this is has turned up in some library code that we are evaluating I
assume that for some compilers, some of the time, this is valid.
Please could someone help explain when it is valid?
If there is no actual definition of functionA in the source file where it is declared it is also not used, the compiler should issue "declared ‘static’ but never defined" as a warning.
However, if you are using the -Werror option the compiler would issue all warnings as errors... check if you are using that option.
https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Your compiler is right, you declared a static function
static int* functionA(int* anInt);
but there is no definition for it, you then added a macro, that will replace every occurrence of functionA(value); in your code with (<a 1 line '? :' function>), hence you can't use the static function anymore even if it had a definition.
A function definition would be
static int *functionA(int* anInt)
{
/* do something with `aInt' */
}
while using the macro, the preprocessor will take this code
#define addnumbers(x, y) ((x) + (y))
double x = addnumbers(1.5, 6.7);
with
double x = ((1.5) + (6.7));
The #define does not define a function, it replaces apparent function calls in the code with an inlined expression. (The expression is ill-formed though unless I miss something; perhaps it is only a placeholder?) The only time the actual compiler sees functionA is in the static declaration; it complains that the function is never defined.
That compiler error comes unexpected to me -- I'd have assumed that the static declaration is ignored if the function is never called. (It is never called because the #define causes those "calls" to be replaced.) One should probably simply #define the static declaration away using an #if/#else construction if the "inlining by #define" is in effect.
By the way, with modern compilers and common optimization levels this should be unnecessary; the compiler would inline the function for you.

How to make GCC evaluate functions at compile time?

I am thinking about the following problem: I want to program a microcontroller (let's say an AVR mega type) with a program that uses some sort of look-up tables.
The first attempt would be to locate the table in a separate file and create it using any other scripting language/program/.... In this case there is quite some effort in creating the necessary source files for C.
My thought was now to use the preprocessor and compiler to handle things. I tried to implement this with a table of sine values (just as an example):
#include <avr/io.h>
#include <math.h>
#define S1(i,n) ((uint8_t) sin(M_PI*(i)/n*255))
#define S4(i,n) S1(i,n), S1(i+1,n), S1(i+2,n), S1(i+3,n)
uint8_t lut[] = {S4(0,4)};
void main()
{
uint8_t val, i;
for(i=0; i<4; i++)
{
val = lut[i];
}
}
If I compile this code I get warnings about the sin function. Further in the assembly there is nothing in the section .data. If I just remove the sin in the third line I get the data in the assembly. Clearly all information are available at compile time.
Can you tell me if there is a way to achieve what I intent: The compiler calculates as many values as offline possible? Or is the best way to go using an external script/program/... to calculate the table entries and add these to a separate file that will just be #included?
The general problem here is that sin call makes this initialization de facto illegal, according to rules of C language, as it's not constant expression per se and you're initializing array of static storage duration, which requires that. This also explains why your array is not in .data section.
C11 (N1570) §6.6/2,3 Constant expressions (emphasis mine)
A constant expression can be evaluated during translation rather than
runtime, and accordingly may be used in any place that a constant may
be.
Constant expressions shall not contain assignment, increment,
decrement, function-call, or comma operators, except when they are
contained within a subexpression that is not evaluated.115)
However as by #ShafikYaghmour's comment GCC will replace sin function call with its built-in counterpart (unless -fno-builtin option is present), that is likely to be treated as constant expression. According to 6.57 Other Built-in Functions Provided by GCC:
GCC includes built-in versions of many of the functions in the
standard C library. The versions prefixed with __builtin_ are always
treated as having the same meaning as the C library function even if
you specify the -fno-builtin option.
What you are trying is not part of the C language. In situations like this, I have written code following this pattern:
#if GENERATE_SOURCECODE
int main (void)
{
... Code that uses printf to write C code to stdout
}
#else
// Source code generated by the code above
... Here I paste in what the code above generated
// The rest of the program
#endif
Every time you need to change it, you run the code with GENERATE_SOURCECODE defined, and paste in the output. Works well if your code is self contained and the generated output only ever changes if the code generating it changes.
First of all, it should go without saying that you should evaluate (probably by experiment) whether this is worth doing. Your lookup table is going to increase your data size and programmer effort, but may or may not provide a runtime speed increase that you need.
If you still want to do it, I don't think the C preprocessor can do it straightforwardly, because it has no facilities for iteration or recursion.
The most robust way to go about this would be to write a program in C or some other language to print out C source for the table, and then include that file in your program using the preprocessor. If you are using a tool like make, you can create a rule to generate the table file and have your .c file depend on that file.
On the other hand, if you are sure you are never going to change this table, you could write a program to generate it once and just paste it in.

Resources