What is __XSI_VISIBLE? - gcc

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>.

Related

Why does gcc misinterpret this macro?

I have found the large-precision code of MPFR C++ to be very useful, and have used it successfully in the past. Recently, while developing a new app, I encountered an enormous number of compiler errors in their header code (mpreal.h). I have identified the cause of all these errors: the the use of a name both in a typedef and as the name of a function, coupled with an unintuitive result of a macro. The relevant macro was in the mpfr package, and occurred between mpfr 4.0.2-5 and 4.1.0-6. I am using the latest version of mpreal.h (version 3.6.8), but other earlier versions behave the same.
The compiler errors vary somewhat, but the following is typical:
In file included from mpreal.h:125:
mpreal.h:624:32: error: no matching function for call to ‘mpfr::mpreal::mpfr_srcptr(const __mpfr_struct*&)’
624 | mpfr_init2(mpfr_ptr(), mpfr_get_prec(u));
| ^~~~~~~~~~~~~
mpreal.h:324:19: note: candidate: ‘const __mpfr_struct* mpfr::mpreal::mpfr_srcptr() const’
324 | ::mpfr_srcptr mpfr_srcptr() const;
| ^~~~~~~~~~~
mpreal.h:324:19: note: candidate expects 0 arguments, 1 provided
The relevant lines of code (int addition to the above) are:
mpreal.h:125 #include <mpfr>
mpfr.h:866 #define mpfr_get_prec(_x) MPFR_VALUE_OF(MPFR_SRCPTR(_x)->_mpfr_prec)
mpfr.h:845 #define MPFR_VALUE_OF(x) (0 ? (x) : (x))
mpfr.h:847 #define MPFR_SRCPTR(x) ((mpfr_srcptr) (0 ? (x) : (mpfr_srcptr) (x)))
The problem seems to be in the macro of line 847. The (mpfr_srcptr) (x) appearing in MPFR_SRCPTR(x) is meant to be a type-cast of x to the type mpfr_srcptr, but is being interpreted to mean a call to mpfr_srcptr() with argument x. Outside of a macro, gcc can tell the difference between (mpfr_srcptr)(x) and mpfr_srcptr(x), but the macro is apparently ignoring the parentheses. Can anyone explain this macro behavior? I know that gcc has a huge number of switches to control almost everything, but is there an option somewhere that would affect the interpretation of parentheses in macros?
I suppose that this behavior could be unique to my system, but I find that hard to believe. But I also find it hard to believe that such a bug has gone unnoticed by the rest of the community; I found no suggestion of any problem either on the website or on github, to which the project has recently been transferred.
The macro SRCPTR is not ignoring parentheses as I originally thought; the behavior is explained by the difference in scopes. The SRCPTR macro, while occurring within the mpfr coding at global scope, is actually being called from mpreal's scope. Since mpreal has redefined srcptr as a function, that definition is the only one used when SRCPTR is executed from mpreal. (SRCPTR, being a macro, has no scope.) When mpfr's functions are called from mpreal, the functions operate with the global scope, and the SRCPTR macro invoked there would therefore use the global definition.

Error when including winuser.h. It defines ChangeMenu to ChangeMenuW or ChangeMenuA

Working on a Qt app on Windows. I include QVboxLayout in my source file only and this causes errors because its macro overwrites my method name.
foo.hpp
class foo
{
ChangeMenu();
}
foo.cpp
#include "foo.hpp"
#include "QVBoxLayout" // <--- this includes winuser.h
foo::ChangeMenu(){};
Now what happens is winuser.h has a macro
#ifdef UNICODE
#define ChangeMenu ChangeMenuW
#else
#define ChangeMenu ChangeMenuA
#endif // !UNICODE
This changes my function definition to ChangeMenuW but my declaration is still ChangeMenu.
How should I solve this? How can winuser.h define such a "normal" name as a macro?
Version of winuser.h is "windows kits\10\include\10.0.16299.0"
Pretty much any Windows API that deals with strings is actually a macro that resolves to a A or W version. There's no way around, you can either:
avoid including windows.h, but as you noticed, it creeps through;
brutally #undef the macro before defining/using your function; this is a fit punishment for hoarding such normal and non-macro-looking identifiers, but is tedious and some other code may actually need the Win32 function;
just accept it as a sad fact of life and avoid all the relevant Win32 APIs names; if you use Qt and follow its naming convention, it should be easy, as Qt functions use lowerCamelCase (as opposed to Win32 UpperCamelCase);
include windows.h explicitly straight in your header (possibly under an #ifdef _WIN32); this will make sure that your identifier will get replaced by the macro in all instances, so everything will work fine even if the compiler will actually compile a function with a different name; suitable for standalone projects, not suitable for libraries. (Thanks #Jonathan Potter for suggesting this)
You could take no care about this issue, Although your method name will be the same as the windows API, but the system will not mix them(just unify Unicode on both the place to define/call). If you call the ChangeMenu() directly, you will call the winapi, and if
foo f;
f.ChangeMenu();
or
foo::ChangeMenu();(static)
You will call your method.
And if you want to disable the winapi:
#ifdef ChangeMenu
#undef ChangeMenu
//code place that you define/call your own ChangeMenu().
#ifdef UNICODE
#define ChangeMenu ChangeMenuW
#else
#define ChangeMenu ChangeMenuA
#endif // !UNICODE
#endif
(It looks very tedious.)

"string safe functions" and gcc

I'm using CodeBlocks and GCC compiler. I'd like to use "string safe functions" e.g strlen_s, strcpy_s, but compiler shows an error:
Undefined reference to strlen_s.
I then add a line to the code:
#define __STDC_WANT_LIB_EXT1__ 1
As well as writing the following in the Compiler Options (settings -> compiler -> global compiler settings -> other compiler options):
-std=c11
In the book that I'm reading there's a code to checking whether my compiler supports these functions. The code is as follows:
#include <stdio.h>
int main()
{
#if defined __STDC_WANT_LIB_EXT1__
printf("optional functions are defined");
#else
printf("optional functions are not defined");
#endif
return 0;
}
When I run this code I see "optional functions are defined". I've also reinstalled CodeBlocks but I still get these errors.
Should I install another compiler? If I should, which one will be the best?
#define __STDC_WANT_LIB_EXT1__ 1 is expected to be defined by your application - you have to define it yourself to enable the use of the bounds-checking interface functions.
In order to see if the bounds-checking interface is at all available, you need to check if __STDC_LIB_EXT1__ is defined by the compiler.
Note that no function called strlen_s exists.
This test is not sufficient, you should also test whether the implementation defines the macro __STDC_LIB_EXT1__.
These functions are from a part of the C standard that is called "Annex K" and that is optional. With this macro you test if your C library provides that feature, with the WANT macro defined before any includes you tell the compiler that you want to use these features from Annex K.
Annex K is much controversial, and not many public domain C libraries implement it. Many people think that its interfaces don't provide the security that it claims.
And for the book that you are reading this doesn't seem to be too reliable. But then, I may be biased on that point.

Since there is no preprocressor in Swift, what replaces C macros?

Is there a way to do #define, #ifdef and the other powerful macros in Swift?
Swift doesn't have a preprocessor and can't use C macros. There are some alternatives though.
For constants you can just use a let statement. For example:
let defaultHeight = 100
There is also some support for build configurations. They have this format.
#if build configuration && !build configuration
statements
#elseif build configuration
statements
#else
statements
#endif
You can replace "build configuration" with the functions os() and arch() that return true or false. os() can take OSX or iOS as arguments while arch() can take x86_64, arm, arm64 and i386 as arguments.
You can see more about how Swift replaces C macros here
Simple Macros
Where you typically used the #define directive to define a primitive constant in C and Objective-C, in Swift you use a global constant instead. For example, the constant definition #define FADE_ANIMATION_DURATION 0.35 can be better expressed in Swift with let FADE_ANIMATION_DURATION = 0.35. Because simple constant-like macros map directly to Swift global variables, the compiler automatically imports simple macros defined in C and Objective-C source files
reference: Page 40, Simple Macros
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/BuildingCocoaApps.pdf

implementing __sync_swap() in gcc

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.

Resources