Compiler ignores #define _GNU_SOURCE - c

I am not a native english speaker, so please excuse any spelling or grammar mistakes
I am not a compiling expert, nor do I have any useful experience with builds and their errors
I am C# programmer and mainly working in an MS Enviroment
I only know the 3 "must know to survive in Linux commands" "./configure, make & make install" from my little Linux Experience
My Development Enviroment
I am using a Windows 7 Workstation
with Cygwin and MinGW (as Linux 'Replacement') to compile.
The Problem
I want to compile C source code on windows, which is primary written for Linux distributions.
/Configure works without problems.
If I use the command make to compile the sources, I run into following error:
Error
grib_keys.c:50:34:
error: 'alphasort' undeclared (first use in this function)
Research:
My Research proved me, that this problem already has been solved, but unfortunately, the answer isn't working for me.
Implicit declaration of scandir; alphasort is undeclared
http://ubuntuforums.org/archive/index.php/t-1653576.html
The solution says, that I only have to include following: #define _GNU_SOURCE
Which I tried, but as already stated, it doesn't work.
I included it in following files:
- grib_keys.c
- config.h
and tried to compile them with concurrent and not concurrent inclusion.
In the end, the important parts of the files looked like this:
config.h
********
/* Add #define _GNU_SOURCE to solve "'alphasort' undeclared" error */
#define _GNU_SOURCE
grib_keys.c
***********
#define _GNU_SOURCE
count = scandir(dir, &files, 0, alphasort);
What I want to achive & to know:
I want to compile the whole sourcecode of below named API, to use the binaries on a windows operating system.
Also I would like to know, whether I wrote the "#define _GNU_SOURCE"-Tag to the right place, or if I made a mistake.
Downloads:
Api
https://software.ecmwf.int/wiki/display/GRIB/Home

If you're going to declare feature-test macros such as _GNU_SOURCE, you must ensure that the preprocessor sees them before it sees any code that uses them. That generally means they have to be processed before any system headers. The best placement, therefore, is at the top of each of your C source files (not headers), before any #include directives.
With that said, you need a solution that applies to the C library you're actually using, and its development headers. For MinGW, it seems that would be Microsoft's C library, which does not appear to document an alphasort() function.
Even if you were using glibc (Cygwin's version, for instance) my glibc docs claim that the needed feature-test macro for alphasort() is either _BSD_SOURCE or _SVID_SOURCE, not _GNU_SOURCE. Since glibc 2.10, it looks like it's probably best to use _POSIX_C_SOURCE >= 200809L, or _XOPEN_SOURCE >= 700, as these reflect the fact that the function was standardized in POSIX.1-2008.

Related

`__noinline__` macro conflict between GLib and CUDA

I'm working on an application using both GLib and CUDA in C. It seems that there's a conflict when importing both glib.h and cuda_runtime.h for a .cu file.
7 months ago GLib made a change to avoid a conflict with pixman's macro. They added __ before and after the token noinline in gmacros.h: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2059
That should have worked, given that gcc claims:
You may optionally specify attribute names with __ preceding and following the name. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use the attribute name __noreturn__ instead of noreturn.
However, CUDA does use __ in its macros, and __noinline__ is one of them. They acknowledge the possible conflict, and add some compiler checks to ensure it won't conflict in regular c files, but it seems that in .cu files it still applies:
#if defined(__CUDACC__) || defined(__CUDA_ARCH__) || defined(__CUDA_LIBDEVICE__)
/* gcc allows users to define attributes with underscores,
e.g., __attribute__((__noinline__)).
Consider a non-CUDA source file (e.g. .cpp) that has the
above attribute specification, and includes this header file. In that case,
defining __noinline__ as below would cause a gcc compilation error.
Hence, only define __noinline__ when the code is being processed
by a CUDA compiler component.
*/
#define __noinline__ \
__attribute__((noinline))
I'm pretty new to CUDA development, and this is clearly a possible issue that they and gcc are aware of, so am I just missing a compiler flag or something? Or is this a genuine conflict that GLib would be left to solve?
Environment: glib 2.70.2, cuda 10.2.89, gcc 9.4.0
Edit: I've raised a GLib issue here
It might not be GLib's fault, but given the difference of opinion in the answers so far, I'll leave it to the devs there to decide whether to raise it with NVidia or not.
I've used nemequ's workaround for now and it compiles without complaint.
GCC's documentation states:
You may optionally specify attribute names with __ preceding and following the name. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use the attribute name __noreturn__ instead of noreturn.
Now, that's only assuming you avoid double-underscored names the compiler and library use; and they may use such names. So, if you're using NVCC - NVIDIA could declare "we use noinline and you can't use it".
... and indeed, this is basically the case: The macro is protected as follows:
#if defined(__CUDACC__) || defined(__CUDA_ARCH__) || defined(__CUDA_LIBDEVICE__)
#define __noinline__ __attribute__((noinline))
#endif /* __CUDACC__ || __CUDA_ARCH__ || __CUDA_LIBDEVICE__ */
__CUDA_ARCH__ - only defined for device-side code, where NVCC is the compiler (ignoring clang CUDA support here).
__CUDA_LIBDEVICE__ - Don't know where this is used, but you're certainly not building it, so you don't care about that.
__CUDACC__ defined when NVCC is compiling the code.
So in regular host-side code, including this header will not conflict with Glib's definitions.
Bottom line: NVIDIA is (basically) doing the right thing here and it shouldn't be a real problem.
GLib is clearly in the right here. They check for __GNUC__ (which is what compilers use to indicate compatibility with GNU C, AKA the GNU extensions to C and C++) prior to using __noinline__ exactly as the GNU documentation indicates it should be used: __attribute__((__noinline__)).
GNU C is clearly doing the right thing here, too. Compilers offering the GNU extensions (including GCC, clang, and many many others) are, well, compilers, so they are allowed to use the double-underscore prefixed identifiers. In fact, that's the whole idea behind them; it's a way for compilers to provide extensions without having to worry about conflicts to user code (which is not allowed to declare double-underscore prefixed identifiers).
At first glance, NVidia seems to be doing the right thing, too, but they're not. Assuming you consider them to be the compiler (which I think is correct), they are allowed to define double-underscore prefixed macros such as __noinline__. However, the problem is that NVidia also defines __GNUC__ (quite intentionally since they want to advertise support for GNU extensions), then proceeds to define __noinline__ in an incompatible way, breaking an API provided by GNU C.
Bottom line: NVidia is in the wrong here.
As for what to do about it, well that's a less interesting question but there are a few options. You could (and should) file an issue with NVidia to fix their compiler. In my experience they're pretty good about responding quickly but unlikely to get around to fixing the problem in a reasonable amount of time.
You could also send a patch to GLib to work around the problem by doing something like
#if defined(__CUDACC__)
__attribute__((noinline))
#elif defined(__GNUC__)
__attribute__((__noinline__))
#else
...
#endif
If you're in control of the code which includes glib, another option would be to do something like
#undef __noinline__
#include glib_or_file_which_includes_glib
#define __noinline__ __attribute__((noinline))
My advice would be to do all three, but especially the first one (file an issue with NVidia) and find a way to work around it in your code until NVidia fixes the problem.

what is WINVER 0x501? RegisterDeviceNotification errors without it

I used RegisterDeviceNotification API in my code. It is not working (getting linker errror), if I'm not using #define WINVER 0x501.
1) When I look into window Winuser.h , RegisterDeviceNotificationA is defined under #if(WINVER >= 0x0500). What is the reason for this?
2) To make RegisterDeviceNotificationA work I declared all the declarations in my own .h file without #if(WINVER >= 0x0500). Is this right way?
3) My another question here is there any problem in declaring RegisterDeviceNotificationA without winver? what is the use of Winver? Please explain me in detail.
The primary purpose of definitions like WINVER is to compile old code with recent compilers.
If you are writing new code, you need to define this variable and maybe several others in your cpp file or in your project file. The value is the version of Windows that you are targeting. This is how Microsoft designed it.
It is extremely bad practice to duplicate system definitions into your code.

Most standard way to select a function name depending on platform?

I am currently using the popen function in code that is compiled by two compilers: MS Visual Studio and gcc (on linux). I might want to add gcc (on MinGW) later.
The function is called popen for gcc, but _popen for MSVS, so i added the following to my source code:
#ifdef _MSC_VER
#define popen _popen
#define pclose _pclose
#endif
This works, but i would like to understand whether there exists a standard solution for such problems (i recall a similar case with stricmp/strcasecmp). Specifically, i would like to understand the following:
Is _MSC_VER the right flag to depend on? I chose it because i have the impression that linux environment is "more standard".
If i put these #define's in some header file, is it important whether i #include it before or after stdio.h (for the case of popen)?
If _popen is defined as a macro itself, is there a chance my #define will fail? Should i use a "new" token like my_popen instead, for that reason or another?
Did someone already do this job for me and made a good "portability header" file that i can use?
Anything else i should be aware of?
Better to check for a windows-specific define (_WIN32 perhaps) because mingw won't have it either. popen() is standardised (it's a part of the Single UNIX® Specification v2)
No; so long as the macro is defined before its first use it does not matter if _popen() is not defined until later.
No; what you have is fine even if _popen is a macro.
It's been done many times but I don't know of a freely-licensed version you can use.
The way you are doing it is fine (with the #ifdef etc) but the macro that you test isn't. popen is something that depends on your operating system and not your compiler.
I'd go for something like
#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 2)
/* system has popen as expected */
#elif defined(YOUR_MACRO_TO DETECT_YOUR_OS)
# define popen _popen
# define pclose _pclose
#elif defined(YOUR_MACRO_TO DETECT_ANOTHER_ONE)
# define popen _pOpenOrSo
# define pclose _pclos
#else
# error "no popen, we don't know what to do"
#endif
_MSC_VER is the correct macro for detecting the MSVC compiler. You can use __GNUC__ for GCC.
If you are going to use popen as your macro ID, I suggest you #include it after, because of 3.
If you #include it after stdio.h, it should work AFAIK, but better safe than sorry, no? Call it portable_popen or something.
Many projects (including some of mine) have a portability header, but it's usually better to roll your own. I'm a fan of doing things yourself if you have the time. Thus you know the details of your code (easier to debug if things go wrong), and you get code that is tailored to your needs.
Not that I know of. I do stuff like this all the time, without problems.
Instead of ending up with cluttered files containing #ifdef..#else..#endif blocks, I'd prefer a version using different files for different platforms:
put the OS dependent definitions in one file per platform and #define a macro my_popen
#include this file in your platform-agnostic code
never call the OS functions directly, but the #define that you created (i.e. my_popen)
depending on your OS, use different headers for compilation (e.g. config/windows/mydefines.h on windows and config/linux/mydefines.h on linux, so set the include path appropriate and always #include "mydefines.h")
That's a much cleaner approach than having the OS decision in the source itself.
If the methods you're calling behave different between windows and linux, decide which one shall be the behavior you're using (i.e. either always windows behavior or always linux behavior) and then create wrapper methods to achieve this. For that, you'll also need not only two mydefines.h files but also to myfunctions.c files that reside in the config/OSTYPE directories.
Doing it that way, you also get advantages when it comes to diff the linux and the windows version: you could simply diff two files while doing a diff on the linux and windows blocks of the same file could be difficult.

What is sys/user.h used for?

I was inspecting the code of a linux application and i saw the #include in one of the code files. I tried looking it up on opengroup.org but i couldn't find it there, this is what the sys directory looks like: http://www.opengroup.org/onlinepubs/000095399/basedefs/sys/ . I guess it's not standard header file, but i checked it in my /usr/include/sys and it was there.
What does it do and what it is used for ? If you can provide me with some manual for it, i would be grateful. Thanks.
Used in conjunction with ptrace(2) (see PTRACE_PEEKUSER): http://linux.die.net/man/2/ptrace
The comment at the top of the header pretty much says it all:
#ifndef _SYS_USER_H
#define _SYS_USER_H 1
/* The whole purpose of this file is for GDB and GDB only. Don't read
too much into it. Don't use it for anything other than GDB unless
you know what you are doing. */
GNU specific extensions are usually pretty easy to identify (e.g. _GNU_SOURCE). However, debugging and instrumentation has to work even if those extensions aren't turned on. For instance, people want to use GDB on code that does not #define _GNU_SOURCE.
In that case, stuff that is not defined in ISO C (and not required by POSIX) is usually clearly labeled as such.
You'll also find all kinds of strange looking symbols in programs that include the Valgrind headers.

C - alternative to #ifdef

I'm trying to streamline large chunk of legacy C code in which, even today, before doing the build guy who maintains it takes a source file(s) and manually modifies the following section before the compilation based on the various types of environment.
The example follows but here's the question. I'm rusty on my C but I do recall that using #ifdef is discouraged. Can you guys offer better alternative? Also - I think some of it (if not all of it) can be set as environment variable or passed in as a parameter and if so - what would be a good way of defining these and then accessing from the source code?
Here's snippet of the code I'm dealing with
#define DAN NO
#define UNIX NO
#define LINUX YES
#define WINDOWS_ES NO
#define WINDOWS_RB NO
/* Later in the code */
#if ((DAN==1) || (UNIX==YES))
#include <sys/param.h>
#endif
#if ((WINDOWS_ES==YES) || (WINDOWS_RB==YES) || (WINDOWS_TIES==YES))
#include <param.h>
#include <io.h>
#include <ctype.h>
#endif
/* And totally insane harcoded paths */
#if (DAN==YES)
char MasterSkipFile[MAXSTR] = "/home/dp120728/tools/testarea/test/MasterSkipFile";
#endif
#if (UNIX==YES)
char MasterSkipFile[MAXSTR] = "/home/tregrp/tre1/tretools/MasterSkipFile";
#endif
#if (LINUX==YES)
char MasterSkipFile[MAXSTR] = "/ptehome/tregrp/tre1/tretools/MasterSkipFile";
#endif
/* So on for every platform and combination */
Sure, you can pass -DWHATEVER on the command line. Or -DWHATEVER_ELSE=NO, etc. Maybe for the paths you could do something like
char MasterSkipFile[MAXSTR] = SOME_COMMAND_LINE_DEFINITION;
and then pass
-DSOME_COMMAND_LINE_DEFINITION="/home/whatever/directory/filename"
on the command line.
One thing we used to do is have a generated .h file with these definitions, and generate it with a script. That helped us get rid of a lot of brittle #ifs and #ifdefs
You need to be careful about what you put there, but machine-specific parameters are good candidates - this is how autoconf/automake work.
EDIT: in your case, an example would be to use the generated .h file to define INCLUDE_SYS_PARAM and INCLUDE_PARAM, and in the code itself use:
#ifdef INCLUDE_SYS_PARAM
#include <sys/param.h>
#endif
#ifdef INCLUDE_PARAM
#include <param.h>
#endif
Makes it much easier to port to new platforms - the existence of a new platform doesn't trickle into the code, only to the generated .h file.
Platform specific configuration headers
I'd have a system to generate the platform-specific configuration into a header that is used in all builds. The AutoConf name is 'config.h'; you can see 'platform.h' or 'porting.h' or 'port.h' or other variations on the theme. This file contains the information needed for the platform being built. You can generate the file by copying a version-controlled platform-specific variant to the standard name. You can use a link instead of copying. Or you can run configuration scripts to determine its contents based on what the script finds on the machine.
Default values for configuration parameters
The code:
#if (DAN==YES)
char MasterSkipFile[MAXSTR] = "/home/dp120728/tools/testarea/MasterSkipFile";
#endif
#if (UNIX==YES)
char MasterSkipFile[MAXSTR] = "/home/tregrp/tre1/tretools/MasterSkipFile";
#endif
#if (LINUX==YES)
char MasterSkipFile[MAXSTR] = "/ptehome/tregrp/tre1/tretools/MasterSkipFile";
#endif
Would be better replaced by:
#ifndef MASTER_SKIP_FILE_PATH
#define MASTER_SKIP_FILE_PATH "/opt/tretools/MasterSkipFile"
#endif
const char MasterSkipFile[] = MASTER_SKIP_FILE_PATH;
Those who want the build in a different location can set the location via:
-DMASTER_SKIP_FILE_PATH='"/ptehome/tregtp/tre1/tretools/PinkElephant"'
Note the use of single and double quotes; try to avoid doing this on the command line with backslashes in the path. You can use a similar default mechanism for all sorts of things:
#ifndef DEFAULTABLE_PARAMETER
#define DEFAULTABLE_PARAMETER default_value
#endif
If you choose your defaults well, this can save a lot of energy.
Relocatable software
I'm not sure about the design of the software that can only be installed in one location. In my book, you need to be able to have the old version 1.12 of the product installed on the machine at the same time as the new 2.1 version, and they should be able to operate independently. A hard-coded path name defeats that.
Parameterize by feature not platform
The key difference between the AutoConf tools and the average alternative system is that the configuration is done based on features, not on platforms. You parameterize your code to identify a feature that you want to use. This is crucial because features tend to appear on platforms other than the original. I look after code where there are lines like:
#if defined(SUN4) || defined(SOLARIS_2) || defined(HP_UX) || \
defined(LINUX) || defined(PYRAMID) || defined(SEQUENT) || \
defined(SEQUENT40) || defined(NCR) ...
#include <sys/types.h>
#endif
It would be much, much better to have:
#ifdef INCLUDE_SYS_TYPES_H
#include <sys/types.h>
#endif
And then on the platforms where it is needed, generate:
#define INCLUDE_SYS_TYPES_H
(Don't take this example header too literally; it is the concept I am trying to get over.)
Treat platform as a bundle of features
As a corollary to the previous point, you do need to detect platform and define the features that are applicable to that platform. This is where you have the platform-specific configuration header which defines the configuration features.
Product features should be enabled in a header
(Elaborating on a comment I made to another answer.)
Suppose you have a bunch of features in the product that need to be included or excluded conditionally. For example:
KVLOCKING
B1SECURITY
C2SECURITY
DYNAMICLOCKS
The relevant code is included when the appropriate define is set:
#ifdef KVLOCKING
...KVLOCKING stuff...
#else
...non-KVLOCKING stuff...
#endif
If you use a source code analysis tool like cscope, then it is helpful if it can show you when KVLOCKING is defined. If the only place where it is defined is in some random Makefiles scattered around the build system (let's assume there are a hundred sub-directories that are used in this), it is hard to tell whether the code is still in use on any of your platforms. If the defines are in a header somewhere - the platform specific header, or maybe a product release header (so version 1.x can have KVLOCKING and version 2.x can include C2SECURITY but 2.5 includes B1SECURITY, etc), then you can see that KVLOCKING code is still in use.
Believe me, after twenty years of development and staff turnover, people don't know whether features are still in use or not (because it is stable and never causes problems - possibly because it is never used). And if the only place to find whether KVLOCKING is still defined is in the Makefiles, then tools like cscope are less helpful - which makes modifying the code more error prone when trying to clean up later.
Its much saner to use :
#if SOMETHING
.. from platform to platform, to avoid confusing broken preprocessors. However any modern compiler should effectively argue your case in the end. If you give more details on your platform, compiler and preprocessor you might receive a more concise answer.
Conditional compilation, given the plethora of operating systems and variants therein is a necessary evil. if, ifdef, etc are most decidedly not an abuse of the preprocessor, just exercising it as intended.
My preferred way would be to have the build system do the OS detection. Complex cases you'd want to isolate the machine-specific stuff into a single source file, and have completely different source files for the different OSes.
So in this case, you'd have a #include "OS_Specific.h" in that file. You put the different includes, and the definition of MasterSkipFile for this platform. You can select between them by specifying different -I (include path directories) on your compiler command line.
The nice thing about doing it this way is that somebody trying to figure out the code (perhaps debugging) doesn't have to wade through (and possibly be misled by) phantom code for a platform they aren't even running on.
I've seen build systems in which most of the source files started something off like this:
#include PLATFORM_CONFIG
#include BUILD_CONFIG
and the compiler was kicked off with:
cc -DPLATFORM_CONFIG="linuxconfig.h" -DBUILD_CONFIG="importonlyconfig.h"
(this may need backslash escapes)
this had the effect of letting you separate out the platform settings in one set of files and the configuration settings in another. Platform settings manages handling library calls that may not exist on one platform or not in the right format as well as defining important size dependent types--things that are platform specific. Build settings handles what features are being enabled in the output.
Generalities
I'm a heretic who has been cast out from the Church of the GNU Autotools. Why? Because I like to understand what the hell my tools are doing. And because I've had the experience of trying to combine two components, each of which insisted on a different, incompatible version of autotools being the default version installed on my computer.
I work by creating one .h file or .c filed for every combination of platform and significant abstraction. I work hard to define a central .h file that says what the interface is. Often this means I wind up creating a "compatibility layer" that insulates me from differences between platforms. Often I wind up using ANSI Standard C whenever possible, instead of platform-specific functionality.
I sometimes write scripts to generate platform-dependent files. But the scripts are always written by hand and documented, so I know what they do.
I admire Glenn Fowler's nmake and Phong Vo's iffe (if feature exists), which I think are better engineered than the GNU tools. But these tools are part of the AT&T Software Technology suite, and I haven't been able to figure out how to use them without buying into the whole AST way of doing things, which I don't always understand.
Your example
There clearly needs to be
extern char MasterSkipFile[];
in a .h file somewhere, and you can then link against a suitable .o.
The conditional inclusion of the "right set of .h files for the platform" is something I would handle by trying to stick to ANSI C when possible, and when not possible, defining a compatibility layer in a platform-specific .h file. As it is, I can't tell what names the #includes are trying to import, so I can't give more specific advice.

Resources