GCC is lacking Clang's builtin __sync_swap(). I have some code that requires it, and I'm trying to figure out the way to mimic this in GCC. The Clang docs allude to this not being as simple as a single __sync_* or __atomic_* operation.
How could __sync_swap() be mimmiced in GCC?
It so appears that __sync_swap is simply an old fashioned name for what can be achieved with more "up to date" built-ins. Lets consider a case in point (atomic macros as implemented by freebsd: http://code.metager.de/source/xref/freebsd/sys/sys/stdatomic.h):
#if defined(__CLANG_ATOMICS)
....
#define atomic_exchange_explicit(object, desired, order) \
__c11_atomic_exchange(object, desired, order)
....
#elif defined(__GNUC_ATOMICS)
....
#define atomic_exchange_explicit(object, desired, order) \
__atomic_exchange_n(&(object)->__val, desired, order)
....
#else
....
#if __has_builtin(__sync_swap)
/* Clang provides a full-barrier atomic exchange - use it if available. */
#define atomic_exchange_explicit(object, desired, order) \
((void)(order), __sync_swap(&(object)->__val, desired))
....
It's fairly clear from the example that freebsd devs consider the newer clang's __c11_atomic_exchange, gcc's __atomic_exchange_n and older __sync_swap (it at all available) to have identical semantics. The later is only used as last resort option, in case newer built-ins are not available.
Related
gcc's manual says the following:
If a macro is redefined with a definition that is not effectively the same as the old one, the preprocessor issues a warning and changes the macro to use the new definition. If the new definition is effectively the same, the redefinition is silently ignored. This allows, for instance, two different headers to define a common macro. The preprocessor will only complain if the definitions do not match.
(emphasis mine)
Is there a way to make gcc more strict and issue a warning when a macro is redefined, regardless of definition?
Example:
#define TEST 1
#define TEST 1
int main(void) {
return 0;
}
Compiling with gcc -Wall -Wextra -Wpedantic does not generate any warning whatsoever.
Techincally speaking, if a header defines an apple as being red, then another wants to make sure everybody knows the apple is red, this should not be an issue. This is the reason behind it. And also to not compromise linking between multiple libraries if they have the same macro definition and the same value.
some h/hxx/hpp header
#define apples red
It's the usual attitude when you see some people wanting to make sure everyone knows they know (we all have these friends or co-workers, don't we? :) ) that apples are red so they state the obvious.
Preprocessor definitions are "compiled" (so-to-speak, rather said, interpreted and replaced or evaluated accordingly) at, well, compile-time. So having the same token defined multiple times is no real overhead on the app, it might just add a bit of compilation time.
The problem is when some wise-guy wants to let you know apples can also be green.
some other h/hxx/hpp header
#define apples green
Then, when you need to use some apples, you end up with:
some c/cxx/cpp file
#include "some_header.h/hxx/hpp"
#include "some_other_header.h/hxx/hpp"
And you end up with "apples " redefined.
Putting aside the daunting task of seeing where the conflict comes from (usually when combining multiple third-party libs/framerworks that might use similar names in macros or have the same acronyms prefixing a macro), this should be enough for you to know there is a conflict.
Keep in mind, this is a warning, so it will not stop the compilation. To treat warnings as errors, use -Werror.
I wouldn't worry about duplicate definitions, to be honest. They won't harm the code. If you really wanna go overkill-mode, you can always do some testing:
#if defined(apples) ...
... or ...
#ifdef apples ...
I was working on a C/C++ project for an embedded system that uses gcc-arm-none-eabi-8-2019-q3-update as a compiler.
I added the use of the strptime function of time.h but initially it was undefined and I found in the compiler inclusions:
#if __XSI_VISIBLE
...strptime...
#endif
So, I solved the problem with:
#undef __XSI_VISIBLE
#define __XSI_VISIBLE 1
#include <time.h>
#undef __XSI_VISIBLE
#define __XSI_VISIBLE 0
Now it works BUT:
What have I done?
What is __XSI_VISIBLE?
What is it for?
Why does this compiler keep it by default at 0?
From https://pubs.opengroup.org/onlinepubs/9699919799/:
The X/Open System Interfaces (XSI) option is the core application programming interface for C and sh programming for systems conforming to the Single UNIX Specification. This is a superset of the mandatory requirements for conformance to POSIX.1-2017.
The __XSI_VISIBLE macro makes visible extensions to "vanilla" POSIX interfaces, which otherwise would be forbidden to be in the name space. Remember that C language standards like ISO C and POSIX permit the application to define all non-standard identifiers (in ISO C and "vanilla" POSIX, strptime is not reserved, you can write a function with that name and have it not interfere). By defining so-called feature test macros you extend the set of standard identifiers and reduce those available to define by the application programmer.
Your compiler keeps it at 0 because the implementation vendor chose that it is the application programmer's job to enable XSI when s/he wants it. Application programmers do this by defining the desired feature test macros before header inclusion, e.g. with
#define _POSIX_SOURCE
#define __XSI_VISIBLE 1
#include <time.h>
or pass -D__XSI_VISIBLE=1 to the compiler.
The correct defs to use are -D_XOPEN_SOURCE=1 and -D_GNU_SOURCE=1. These are used to conditionally define __XSI_VISIBLE and __GNU_VISIBLE respectively in <sys/features.h>. Defining __XSI_VISIBLE and __GNU_VISIBLE will not always work because they are overridden in <sys/features.h>.
I'm looking for a simple way to localize certain g++ (g++-4.9 to be specific) compile options to certain lines of code or at least targeted functions. I'm interested generally speaking, but also specifically to the -fast-math, -ffinite-math-only and -fno-signed-zeros options.
I presume that localization at the *.cpp file level is possible with make utility, but I'm hoping there is a way to enable it in the code itself, through #pragma or __attribute__ or something. I want to do this not only to minimize dependencies to external files (i.e. risk of incorrect makefile) but also to hopefully hyperlocalize certain FP behavior to specific equations within a function.
Alternatively, if localization of FP behavior by inline directives is NOT possible, what can I do to at least trigger a compile time error if desired compiler directive is NOT enabled in project build (e.g. makefile is lost or inappropriately modified).
I would presume that such inline optimization might be compiler specific, g++ in this case, but that is a compromise I'm willing to take.
In gcc you can use function attribute optimize:
void f () __attribute__ ((optimize("fast-math"), optimize("finite-math-only"), optimize("no-signed-zeros")));
I'm not sure that you are using the "localize" word correctly. Localization is related to adapting software to users of different human languages (French, Russian, Chinese...)
Perhaps you want to ask the compiler to optimize some functions with other optimization flags.
This is possible using #pragma GCC optimize etc... or using some function attributes
You might be able to turn on some bits of this with the fpmath option in a function attribute, but this was not clear to me from the docs. In light of that, I will focus on detection instead:
-fast-math already turns on -ffinite-math-only, so you don't need to worry about that. The docs for -fast-math say:
This option causes the preprocessor macro FAST_MATH to be
defined.
Which means it can be detected via
#ifndef __FAST_MATH__
#error "The -fast-math compiler option is required"
#endif
I have not yet found a compile-time way to detect the presence of -fno-signed-zeros
I'm currently using GCC 4.5.3, compiled for PowerPC 440, and am compiling some code that doesn't require libc. I don't have any direct calls to memcpy(), but the compiler seems to be inserting one during the build.
There are linker options like -nostdlib, -nostartfiles, -nodefaultlibs but I'm unable to use them as I'm not doing the linking phase. I'm only compiling. With something like this:
$ powerpc-440-eabi-gcc -O2 -g -c -o output.o input.c
If I check the output.o with nm, I see a reference to memcpy:
$ powerpc-440-eabi-nm output.o | grep memcpy
U memcpy
$
The GCC man page makes it clear how to remove calls to memcpy and other libc calls with the linker, but I don't want the compiler to insert them in the first place, as I'm using a completely different linker (not GNU's ld, and it doesn't know about libc).
Thanks for any help you can provide.
There is no need to -fno-builtins or -ffreestanding as they will unnecessarily disable many important optimizations
This is actually "optimized" by gcc's tree-loop-distribute-patterns, so to disable the unwanted behavior while keeping the useful builtin capabilities, you can just use:
-fno-tree-loop-distribute-patterns
Musl-libc uses this flag for its build and has the following note in their configure script (I looked through the source and didn't find any macros, so this should be enough)
# Check for options that may be needed to prevent the compiler from
# generating self-referential versions of memcpy,, memmove, memcmp,
# and memset. Really, we should add a check to determine if this
# option is sufficient, and if not, add a macro to cripple these
# functions with volatile...
# tryflag CFLAGS_MEMOPS -fno-tree-loop-distribute-patterns
You can also add this as an attribute to individual functions in gcc using its optimize attribute, so that other functions can benefit from calling mem*()
__attribute__((optimize("no-tree-loop-distribute-patterns")))
size_t strlen(const char *s){ //without attribute, gcc compiles to jmp strlen
size_t i = -1ull;
do { ++i; } while (s[i]);
return i;
}
Alternatively, (at least for now) you may add a confounding null asm statement into your loop to thwart the pattern recognition.
size_t strlen(const char *s){
size_t i = -1ull;
do {
++i;
asm("");
} while (s[i]) ;
return i;
}
Gcc emits call to memcpy in some circumstance, for example if you are copying a structure.
There is no way to change GCC behaviour but you can try to avoid this by modifying your code to avoid such copy. Best bet is to look at the assembly to figure out why gcc emitted the memcpy and try to work around it. This is going to be annoying though, since you basically need to understand how gcc works.
Extract from http://gcc.gnu.org/onlinedocs/gcc/Standards.html:
Most of the compiler support routines used by GCC are present in libgcc, but there are a few exceptions. GCC requires the freestanding environment provide memcpy, memmove, memset and memcmp. Finally, if __builtin_trap is used, and the target does not implement the trap pattern, then GCC will emit a call to abort.
You need to disable a that optimization with -fno-builtin. I had this problem once when trying to compile memcpy for a C library. It called itself. Oops!
You can also make your binary a "freestanding" one:
The ISO C standard defines (in clause 4) two classes of conforming implementation. A conforming hosted implementation supports the whole standard [...]; a conforming freestanding implementation is only required to provide certain library facilities: those in , , , and ; since AMD1, also those in ; and in C99, also those in and . [...].
The standard also defines two environments for programs, a freestanding environment, required of all implementations and which may not have library facilities beyond those required of freestanding implementations, where the handling of program startup and termination are implementation-defined, and a hosted environment, which is not required, in which all the library facilities are provided and startup is through a function int main (void) or int main (int, char *[]).
An OS kernel would be a freestanding environment; a program using the facilities of an operating system would normally be in a hosted implementation.
(paragraph added by me)
More here. And the corresponding gcc option/s (keywords -ffreestanding or -fno-builtin) can be found here.
This is quite an old question, but I've hit the same issue, and none of the solutions here worked.
So I defined this function:
static __attribute__((always_inline)) inline void* imemcpy (void *dest, const void *src, size_t len) {
char *d = dest;
const char *s = src;
while (len--)
*d++ = *s++;
return dest;
}
And then used it instead of memcpy. This has solved the inlining issue for me permanently. Not very useful if you are compiling some sort of library though.
Is there an option that the GCC preprocessor could generate C source code and filter out irrelevant source code?
For example, a .c file has a #define switch to define for many different platforms. I'm only interested in one platform, and I want the C preprocessor to filter out unrelated code.
Does GCC support this?
Yes. Use the -E option:
gcc -E foo.c
While the -E option will perform all pre-processing, it also produces some very 'raw' output that might not be what you want (depending on what you want).
If you need to debug a macro expansion that's not doing what you expect, E is a good way to go. If you simply want to filter out the 'inactive code', but leave the remaining code in more-or-less original form, you might want to look at the answers to the following Stack Overflow question:
Is there a C pre-processor which eliminates #ifdef blocks based on values defined/undefined?
It sounds like you want unifdef, not the GCC preprocessor.