How to #ifdef the __builtin_prefetch function - c

How do I keep __builtin_prefetch() in my code, but make compilers that do not have it compile successfully? (Just doing nothing where it is found).

__builtin_prefetch() is recognised by the compiler (gcc) not the preprocessor, so you won't be able to detect it using the C preprocessor.
Since an identifier with two leading underscores is reserved for use by the implementation (so any code you use which defines such an identifier has undefined behaviour) I'd do it the other way around.
#ifdef __GNUC__
#define do_prefetch(x) __builtin_prefetch(x)
#else
#define do_prefetch(x)
#endif
and then use
do_prefetch(whatever);
where needed.
That way there is no code emitted unless it is actually needed.
Since __builtin_prefetch() accepts a variable number of arguments, you might want to adapt the above to use variadic macros (C99 and later) - if you use it with different numbers of arguments in different places in your code.

It is not exactly the best solution, but it will disable __builtin_prefetch() on all other compilers other than GCC.
#ifndef __GNUC__
# define __builtin_prefetch(x)
#endif

Related

Is calling atoi without stdlib undefined behaviour?

Is calling atoi without including stdlib.h undefined behaviour?
I can't find where I have included stdlib.h in my project, even though I have used atoi.
The thing is actually atoi has been working fine - it has been parsing integers correctly every time the software has been used.
It is some embedded device.
So is there case this can be well defined?
btw. In this line:
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* __cplusplus */
#include "sdkGlob.h"
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
that header includes stdlib.h but I can't understand in which case it is included. And I am not sure if this cplusplus is defined anywhere. This is a c project anyway.
Prior to C99 it was acceptable to use functions that hadn't previously been declared. The compiler might generate a warning but there would be no error until the linker either didn't find the function or found a function of the same name with a signature other than the one that the compiler had guessed. Luckily for you, the compiler always guesses a return type of int.
In C99 it became necessary for function declarations to be visible but not all compilers strictly enforce the rule.
As per Random832's comment, it's also quite possible that sdkGlob simply includes stdlib for itself.
As to your other question: sdkGlob is always included but if run through a C++ compiler rather than a C compiler you also get the extern "C"{ .. } wrapping. That tells the C++ compiler not to mangle the names so that you can link against a version of that module that was built using an ordinary C compiler. It's the normal way to provide plain C libraries in a way that allows them to be used by both C and C++ code.
The short answer
Two possibilities:
It's probable that sdkGlob.h include stdlib.h or define its own version of atoi.
Some compilers, like GCC, resolve missing #include and even hide the errors or warnings. Run gcc -Wall and check if warnings appears.
About ifndef
The #ifdef __cplusplus sections are used by C++ compilers. Here, you're saying '*if and if only the code is being compiled by a C++ compiler, do ... *'.
The C-only version of your code:
#include "sdkGlob.h"
The C++-only version of your code:
extern "C"{
#include "sdkGlob.h"
}

How to #ifdef by CompilerType ? GCC or VC++

I used #ifdef Win32 for safe calls alike sprintf_s but now I want to build project with MinGW and it's just wrong now. I need to use #ifdef VC++ or somehow like that. Is it possible?
#ifdef __clang__
/*code specific to clang compiler*/
#elif __GNUC__
/*code for GNU C compiler */
#elif _MSC_VER
/*usually has the version number in _MSC_VER*/
/*code specific to MSVC compiler*/
#elif __BORLANDC__
/*code specific to borland compilers*/
#elif __MINGW32__
/*code specific to mingw compilers*/
#endif
See the "Microsoft-Specific Predefined Macros" table of Visual C predefined macros
You could check for _MSC_VER.
Preferably, you should resort to using portable symbols. I understand sometimes those symbols may not be defined, so you can see the Predef project for an extensive list of preprocessor macros regarding standards, compilers, libraries, operating systems and architectures that aren't portable.
However, the function you specifically mention in this question has been included within the C11 standard as a part of Annex K.3, the bounds-checking interfaces (library).
K.3.1.1p2 states:
The functions, macros, and types declared or defined in K.3 and its subclauses are declared and defined by their respective headers if __STDC_WANT_LIB_EXT1__ is defined as a macro which expands to the integer constant 1 at the point in the source file where the appropriate header is first included
Thus, you should place preference upon checking __STDC_WANT_LIB_EXT1__, and only use compiler-specific symbols when that doesn't exist.

How to copy macro contents to another macro in C [duplicate]

I am using both the JUCE Library and a number of Boost headers in my code. Juce defines "T" as a macro (groan), and Boost often uses "T" in it's template definitions. The result is that if you somehow include the JUCE headers before the Boost headers the preprocessor expands the JUCE macro in the Boost code, and then the compiler gets hopelessly lost.
Keeping my includes in the right order isn't hard most of the time, but it can get tricky when you have a JUCE class that includes some other classes and somewhere up the chain one file includes Boost, and if any of the files before it needed a JUCE include you're in trouble.
My initial hope at fixing this was to
#undef T
before any includes for Boost. But the problem is, if I don't re-define it, then other code gets confused that "T" is not declared.
I then thought that maybe I could do some circular #define trickery like so:
// some includes up here
#define ___T___ T
#undef T
// include boost headers here
#define T ___T___
#undef ___T___
Ugly, but I thought it may work.
Sadly no. I get errors in places using "T" as a macro that
'___T___' was not declared in this scope.
Is there a way to make these two libraries work reliably together?
As greyfade pointed out, your ___T___ trick doesn't work because the preprocessor is a pretty simple creature. An alternative approach is to use pragma directives:
// juice includes here
#pragma push_macro("T")
#undef T
// include boost headers here
#pragma pop_macro("T")
That should work in MSVC++ and GCC has added support for pop_macro and push_macro for compatibility with it. Technically it is implementation-dependent though, but I don't think there's a standard way of temporarily suppressing the definition.
Can you wrap the offending library in another include and trap the #define T inside?
eg:
JUICE_wrapper.h:
#include "juice.h"
#undef T
main.cpp:
#include "JUICE_wrapper.h"
#include "boost.h"
rest of code....
I then thought that maybe I could do some circular #define trickery like so:
The C Preprocessor doesn't work this way. Preprocessor symbols aren't defined in the same sense that a symbol is given meaning when, e.g., you define a function.
It might help to think of the preprocessor as a text-replace engine. When a symbol is defined, it's treated as a straight-up text-replace until the end of the file or until it's undefined. Its value is not stored anywhere, and so, can't be copied. Therefore, the only way to restore the definition of T after you've #undefed it is to completely reproduce its value in a new #define later in your code.
The best you can do is to simply not use Boost or petition the developers of JUCE to not use T as a macro. (Or, worst case, fix it yourself by changing the name of the macro.)

Why does GCC's __attribute__((...)) syntax use double parentheses?

The documentation for GCC's __attribute__((...)) syntax indicates that attributes must be surrounded by double parentheses, but does not give a rationale for this design decision.
What practical reason would have caused GCC's designers to require this? Does it have anything to do with the preprocessor's handling of double parentheses?
To make it easier to eliminate it for different compiler. If you have portable code, you have to remove them for other compilers, so you do
#ifndef __GNUC__
#define __attribute__(x)
#endif
The problem is that attributes have various number of arguments and you can combine multiple attributes in one __attribute__ declaration, but C only introduced variadic macros in C99. With double parenthesis the above definition does not need variadic macros.
probably the idea is that you can declare a simple macro that helps to ignore all this in any other C and C++ compiler. If you wouldn't have the second pair of parenthesis that macro would be necessarily one with .... So for compilers that don't support that you would be screwed.
Edit: With this syntax it can simply look like
#ifdef __GNUC__
# define attribute(X) __attribute__(X)
#else
# define attribute(X)
#endif
and then you would use attribute for your function declarations, e.g.

What does "#define assert(exp) ((void) 0)" do?

I came across this preprocessor definition while reading the source code in Windows Research Kernel (WRK) 1.2:
#define assert(exp) ((void) 0)
What does this code do? Why is it defined?
It defines the expression assert(anything) to do nothing.
Presumably, the environment being used does not support the ANSI C assert statement, or the programmer was unaware of the fact that it could be disabled by defining NDEBUG.
To expand on what bdonlan says, the reason the macro does not expand empty is because if it did, then something like:
assert(something) // oops, missed the semi-colon
assert(another_thing);
would compile in release mode but not in debug mode. The reason it is ((void) 0) rather than just 0 is to prevent "statement with no effect" warnings (or whatever MSVC calls them).
Just to add, this is the definition of assert in newlib too, when NDEBUG is defined as a preprocessor directive. Newlib is the open source C library that is used on Cygwin and embedded systems.
From the assert manual in newlib:
The macro is defined to permit you to turn off all uses of assert at
compile time by defining NDEBUG as a preprocessor variable. If you do this,
the assert macro expands to (void(0))

Resources