I am trying to write some library code that may be used by people who have pthreads enabled (or not), and by people who have openmp support (or not). I have some variable that I really want to be in thread-local storage. Is there any potential harm in specifying this twice, for example
#ifdef __GNUC__
# define PREFIX __thread
#elif __STDC_VERSION__ >= 201112L
# define PREFIX _Thread_local
#elif defined(_MSC_VER)
# define PREFIX __declspec(thread)
#else
# define PREFIX
#endif
PREFIX int var = 10;
#pragma omp threadprivate(var)
(Note, the business to figure out the TLS prefix is taken from How to declare a variable as thread local portably?)
I know this works on my system (Debian with recent gcc) but it's hard to know whether things could go wrong elsewhere since these compiler-specific declarations are not part of the OpenMP standard.
What about:
#if __STDC_VERSION__ >= 201112L
# define PREFIX _Thread_local
#elif defined(__GNUC__)
# define PREFIX __thread
#elif defined(_MSC_VER)
# define PREFIX __declspec(thread)
#else
# define PREFIX
#endif
PREFIX int var = 10;
#if !PREFIX
#ifdef _OPENMP
#pragma omp threadprivate(var)
#else
#error "Failure to put variable into TLS"
#endif
#endif
GCC doesn't mind the over-specifying because __thread is an implicit #pragma omp threadprivate anyway.
Instead of worrying about compilers where this might not be the case, just use OpenMP's threadprivate conditionally.
Related
Is it possible to put a #endif inside a #if as the block's 'content' not as the pair #endif for the #if?
#if (SOME_CONDITION)
#if (ANOTHER_CONDITION)
#endif // pair endif for #if (SOME_CONDITION)
#if (SOME_CONDITION)
#endif // pair endif for #if (ANOTHER_CONDITION)
#endif // pair endif for #if (SOME_CONDITION)
If this is not possible how to conditionally compile a #if ... #endif pair?
This is what I was doing.
I was modifying a code base that we bought from another company. To compile it with and without my modifications easily I was using a macro say like shown below.
#if (MY_COMPANY_EDITS_ENABLED)
// My Modified code goes here
#else
// unmodified code from another company
#endif
In this way I could easily compile in/out my modifications while maintaining readability about my edits. I was using the same #if #else #endif blocks everywhere. But then I came across a code that is being compiled in, in the original unmodified code base, based on some macro value.
#if (FEATURE_A_IS_ENABLED)
// Line 1
// Line 2
#endif
But I want to compile this code [Line 1 and Line 2] regardless of the macro value FEATURE_A_IS_ENABLED
My first thought was to follow the same convention that I used till now [to maintain readability about my edits].
#if (MY_COMPANY_EDITS_ENABLED)
//#if (FEATURE_A_IS_ENABLED)
#else
#if (FEATURE_A_IS_ENABLED)
#endif
// Line 1
// Line 2
#if (MY_COMPANY_EDITS_ENABLED)
// #endif
#else
#endif
#endif
Then I realized this is not possible.
I know, alternative methods exist to achieve the same. But was wondering whether I could use the same convention
#if (MY_COMPANY_EDITS_ENABLED)
// My Modified code goes here
#else
// unmodified code from another company
#endif
in this case too.
No, it's not possible. The first #endif will be matched with the most recent #if or #else, so your code will be interpreted like this:
#if (SOME_CONDITION)
#if (ANOTHER_CONDITION)
#endif // pair endif for #if (ANOTHER_CONDITION)
#if (SOME_CONDITION)
#endif // pair endif for the second #if (SOME_CONDITION)
#endif // pair endif for the first #if (SOME_CONDITION)
This is not possible, as the preprocessor only does a single pass over your file, and the #endif gets matched with the preceding #if. If you want to make an #if/#endif block conditional, then just nest it inside another #if/#endif block:
#if CONDITION_A
# if CONDITION_B
...
# endif /* CONDITION_B */
#endif /* CONDITION_A */
Put another way, it's not possible to have preprocessing directives construct other preprocessing directives, as the output from the initial "construction" phase will not be reparsed by the preprocessor.
The (silly) example below wouldn't work either for example, even assuming the newlines wouldn't be an issue (which they would be here):
#if DEFINE_X_TO_FIVE
#define X
#endif
#if DEFINE_X_TO_FIVE
5
#endif
I recommend making the changes based on feature sets rather than whether or not they are yours or not then group them together to make a given version (MY_COMPANY_EDITS_ENABLED) or whatever:
#if (MY_COMPANY_EDITS_ENABLED)
#define FEATUREA
#define FEATUREB
#define FEATUREC
#define FEATURED
#else
#define FEATUREA
#undef FEATUREB
#undef FEATUREC
#undef FEATURED
#endif
#ifdef FEATUREA
//do some feature A stuff
#endif
// do code
#ifdef FEATUREB
//do some feature B stuff
#endif
#ifndef FEATUREC
//do some stuff if not feature C
#endif
// etc...
This is a lot more flexible in the long run and lets you switch changes features on and off with a rebuild.
Off course you can nest your preprocessor directives:
#ifdef CONDITION1
// some code here
# ifdef CONDITION2
// some else here
# endif
#endif
But make sure to end each condition properly.
See also: http://www.ioccc.org/years.html#1995_vanschnitz and http://www.ioccc.org/years.html#2004_vik2
C11 introduces the _Thread_local storage class specifier that can be used in combination with the static and extern storage class specifiers to declare a variable as thread local. The GNU C compiler suite implements a storage class specifier __thread with the same same semantics.
Unfortunately I did not find any compiler (I tried gcc, clang and SUN studio) that actually implements the _Thread_local keywords. I currently use the following construct to declare a keyword thread_local:
/* gcc doesn't know _Thread_local from C11 yet */
#ifdef __GNUC__
# define thread_local __thread
#elif __STDC_VERSION__ >= 201112L
# define thread_local _Thread_local
#else
# error Don't know how to define thread_local
#endif
I know that this probably does not work with MSVC and other compilers. Can anybody suggest me a better method to declare thread_local in a way that it works in as many compilers as possible?
Edit
Christoph suggested that Microsoft Visual C allows __declspec(thread). This is the updated macro definition:
/* gcc doesn't know _Thread_local from C11 yet */
#ifdef __GNUC__
# define thread_local __thread
#elif __STDC_VERSION__ >= 201112L
# define thread_local _Thread_local
#elif defined(_MSC_VER)
# define thread_local __declspec(thread)
#else
# error Cannot define thread_local
#endif
Combining information from Wikipedia with this list of compiler macros, I came up with the following (untested) version:
#ifndef thread_local
# if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__
# define thread_local _Thread_local
# elif defined _WIN32 && ( \
defined _MSC_VER || \
defined __ICL || \
defined __DMC__ || \
defined __BORLANDC__ )
# define thread_local __declspec(thread)
/* note that ICC (linux) and Clang are covered by __GNUC__ */
# elif defined __GNUC__ || \
defined __SUNPRO_C || \
defined __xlC__
# define thread_local __thread
# else
# error "Cannot define thread_local"
# endif
#endif
I have functions which abstract serial- and socket IO (Linux / Windows) implemented in C.
All of them are marked as extern "C" because they may get called from C++ as well.
Is it safe to use __attribute__((__nothrow__)) (or MinGW Macro __MINGW_NOTHROW) here / can i assume no exceptions are thrown?
Called functions - Sockets:
(not all additions for WinSock listed)
socket
connect
send / recv
close (closesocket on Windows)
sendto / recvfrom
Called functions - Serial:
Since serial IO code differs to much between windows / linux not all are listed here
Linux (GNU)
open
tcgetattr
read / write
close
Windows (MinGW)
CreateFile
GetCommState / SetCommTimeouts
ReadFile / WriteFile
CloseHandle
Since ANSI C has no exceptions (please correct me if I'm wrong) they won't be thrown, but how about GCC extensions and OS API calls?
Documentation: http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html (see nothrow).
C
GNU C (Linux) uses __THROW macro instead of __MINGW_NOTHROW.
While the MinGW one is __nothrow__ attribute only, __THROW contains __leaf__ attribute too.
C++
If you use C++, __THROW has another meaning: throw() - indicating that no exception is thrown (analog to __nothrow__; but defined in the C++ standard).
So it depends on whether you compile with C or C++, not on what you call the functions from (GNU C / C++ only!).
Example:
void f() __THROW;
Treated as ...
GNU C:
void f() __attribute__((__nothrow__, __leaf__))
GNU C++:
void f() throw()
Functions1) which are cancellation points, therefore not marked with
__THROW:
open()
read()
write()
close()
connect()
send()
recv()
close()
sendto()
recvfrom()
Functions1) marked with __THROW:
tcgetattr()
socket()
At least, these are save to __nothrow__.
In contrast, MinGW doesn't differ C from C++; in both cases the attribute is set.
Using example from above, __nothrow__ is set on C and C++:
void f() __attribute((__nothrow__))
Functions1) not marked with __MINGW_NOTHROW:
socket()
connect()
send()
recv()
closesocket()
sendto()
recvfrom()
CreateFile()
GetCommState()
SetCommTimeouts()
ReadFile()
WriteFile()
CloseHandle()
To make it short: none!
Compatibility
With C
C language code that is expecting to interoperate with C++ should be
compiled with -fexceptions. This will make debugging a C language
function called as part of C++-induced stack unwinding possible.
In particular, unwinding into a frame with no exception handling data
will cause a runtime abort. If the unwinder runs out of unwind info
before it finds a handler, std::terminate() is called.
Please note that most development environments should take care of
getting these details right. For GNU systems, all appropriate parts of
the GNU C library are already compiled with -fexceptions.
( source: http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html )
So compiling with -fexceptions and there's no need for equivalent attribute. If you only can mark specific functions you have to / should use __nothrow__.
But while using __nothrow__ attribute looks save only on GNU C++, and some functions of GNU C on Linux, it's not that clear on Windows.
Addendum:
To avoid some parts of this problem, i've written a macro similar to __THROW but usable on MinGW too:
#if defined __GNUC__
#ifndef __THROW
#ifdef __cplusplus
#define __THROW throw()
#else
#define __THROW __attribute__((__nothrow__))
#endif
#endif
#else
#define __THROW
#endif
Note: __leaf__ is not included.
1) Talking only about those which are listed on my question.
take care of gcc version, nothrow has been introduced with gcc 3.3!
you can port __THROW from sys/cdefs.h to mingw:
/* skip this entire part on linux (= glibc available)*/
#if defined __GNUC__ && !defined __linux__
/********* port __GNUC_PREREQ macro to mingw *********/
# if !defined __GNUC_PREREQ
# if !defined __MINGW_H
# include <_mingw.h>
# define __GNUC_PREREQ(major, minor) __MINGW_GNUC_PREREQ(major, minor)
# else
# if defined (__GNUC_MINOR__)
# define __GNUC_PREREQ(major, minor) __GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
# else
# define __GNUC_PREREQ(major, minor) 0
# endif
# endif
#endif /* __GNUC_PREREQ */
/********* from gnu c blirary *********/
/* All functions, except those with callbacks or those that
synchronize memory, are leaf functions. */
# if __GNUC_PREREQ (4, 6) && !defined _LIBC
# define __LEAF , __leaf__
# define __LEAF_ATTR __attribute__ ((__leaf__))
# else
# define __LEAF
# define __LEAF_ATTR
# endif
/* GCC can always grok prototypes. For C++ programs we add throw()
to help it optimize the function calls. But this works only with
gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions
as non-throwing using a function attribute since programs can use
the -fexceptions options for C code as well. */
# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
# define __THROW __attribute__ ((__nothrow__ __LEAF))
# define __THROWNL __attribute__ ((__nothrow__))
# define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct
# else
# if defined __cplusplus && __GNUC_PREREQ (2,8)
# define __THROW throw ()
# define __THROWNL throw ()
# define __NTH(fct) __LEAF_ATTR fct throw ()
# else
# define __THROW
# define __THROWNL
# define __NTH(fct) fct
# endif
# endif
#else /* Not GCC. */
# define __inline /* No inline functions. */
# define __THROW
# define __THROWNL
# define __NTH(fct) fct
#endif /* GCC. */
see glibc - sys/cdefs.h for full code.
edit: __GNUC_PREREQ can be replaced with __MINGW_GNUC_PREREQ(major, minor), then you don't have to redifine it as above.
i'm really noob in C. I just need to compile a ANSI C source to get a dll.
During compilation i get this error:
C2491: 'SelectML': definition of dllimport function not allowed
Where SelectML is a public function with this definition:
int CALLINGCONV SelectML(WORD fid, int nSlot)
{
WORD SW;
int x;
BYTE pSend[2];
pSend[0]=(BYTE)((fid&0xff00)>>8);
pSend[1]=(BYTE)(fid&0x00ff);
x=SendAPDUML(hCards[nSlot],APDU_SELECT,2,0,pSend,0,&SW);
if (x!=C_OK) return x;
if (SW!=0x9000) return SW;
return C_OK;
}
I'm sure the C source is good, maybe it is just a Visual Studio configuration...
This is another linked header:
#ifndef LIBSIAECARDT_H
#define LIBSIAECARDT_H
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(USE_STDCALL)
#define USE_STDCALL 1
#endif
#ifdef _WIN32
# if USE_STDCALL == 1
# define CALLINGCONV_1 _stdcall
# else
# define CALLINGCONV_1
# endif
# if defined(LIBSIAE_EXPORTS)
# define LIBSIAEAPI __declspec(dllexport)
# else
# define LIBSIAEAPI __declspec(dllimport)
# endif
# define CALLINGCONV LIBSIAEAPI CALLINGCONV_1
#else // ! _WIN32
# define CALLINGCONV
# define LIBSIAEAPI
# define CALLINGCONV_1
typedef unsigned int UINT;
#endif // _WIN32
It's common to have a macro like CALLINGCONV conditionally defined as __declspec(dllimport) or __declspec(dllexport) so that the same header file can be used in the library source and in the code using the library. Your build should probably define something that makes it use dllexport. Check how CALLINGCONV is defined or (preferably) consult any build documentation that came with the code.
Quoted in MSDN says it all. Do not define the function. Declaration is good. What you are doing here is defining SelectML which for sure is generating your C2491 Error.
Here's an alternative. Stop using MSVC. They explicitly dropped support for anything after C90. Use an actual C compiler for C code.
What is the difference (if any) between the two following preprocessor control statements.
#if
and
#ifdef
You can demonstrate the difference by doing:
#define FOO 0
#if FOO
// won't compile this
#endif
#ifdef FOO
// will compile this
#endif
#if checks for the value of the symbol, while #ifdef checks the existence of the symbol (regardless of its value).
#ifdef FOO
is a shortcut for:
#if defined(FOO)
#if can also be used for other tests or for more complex preprocessor conditions.
#if defined(FOO) || defined(BAR)