In Xcode can I use ## in a macro?
In MSVC I can write:
#define FOO(_var) int foo##_var## = 1
FOO(bar);
foobar++;
On the Mac (edit: compiling with GCC) the same code gives me the error "Pasting "foobar" and "=" does not give a valid preprocessing token. Is ## not supported in xcode?
Concatenation is supported in GCC and Clang. Xcode isn't a compiler; if you're posting errors like this, check what version of GCC, LLVM-GCC or Clang ("LLVM compiler") you're using because their behavior can differ.
You're trying to make = part of an identifier (i.e., create a variable called foobar=) which I don't think is what you want.
Try #define FOO(_var) int foo##_var = 1 instead.
Incidentally, Clang gives a somewhat better error message:
foo.c:4:5: error: pasting formed 'foobar=', an invalid preprocessing token
FOO(bar);
^
foo.c:1:32: note: instantiated from:
#define FOO(_var) int foo##_var## = 1
^
Related
I have some preprocessor code like this:
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
#if GCC_VERSION < 40503
#error Your compiler is outdated.
#error You need at least gcc 4.5.3 for this library.
#error You have: GCC_VERSION
#error You have: STR(GCC_VERSION)
#endif
However both ways I tried to output the current compiler version fail. According to the documentation this is because
Neither ‘#error’ nor ‘#warning’ macro-expands its argument. Internal whitespace sequences are each replaced with a single space. The line must consist of complete tokens. It is wisest to make the argument of these directives be a single string constant; this avoids problems with apostrophes and the like.
How can I output the compiler version with the error message anyway? Is there any preprocessor magic that allows me to achieve this?
The classic "solution" to this problem is to manage to generate an error which includes the desired message. For example:
#define S(x) #x
#define STR(x) S(x)
#if GCC_VERSION < 40503
#error Outdated compiler: you need at least gcc 4.5.3 for this library.
#define above_message_indicates_installed_gcc_version STR(Installed GCC version: GCC_VERSION)
#include above_message_indicates_installed_gcc_version
#endif
While that does provide some information, it is still subject to misinterpretation; personally, I think letting the developer know the minimum version required is sufficient.
Note: The above snippet assumes that GCC_VERSION has already been defined, which I assume must have been done before the snippet in the OP. But beware: since the preprocessor does text substitution, not arithmetic evaluation (except in #if directives), you need to assemble GCC_VERSION in a different form for the error message If you want to try this, you could use the following:
#define GCC_VERSION (__GNUC_PATCHLEVEL__ + 100 * (__GNUC_MINOR__ + 100 * __GNUC__))
#define S_(x) #x
#define STR(x) S_(x)
#if GCC_VERSION < 40503
#undef GCC_VERSION
#define GCC_VERSION __GNUC__.__GNUC_MINOR__.__GNUC_PATCHLEVEL__
#error Outdated compiler: you need at least gcc 4.5.3 for this library.
#define above_message_indicates_installed_gcc_version STR(Installed GCC version: GCC_VERSION)
#include above_message_indicates_installed_gcc_version
#endif
See it on gcc.godbolt
If #error does not expand its arguments, I would just take a pragmatic approach:
#if GCC_VERSION < 40503
#error Outdated compiler < 4.5.3, run 'gcc --version' to get version.
#endif
The only other possibility I can think of is to preprocess the file with your own preprocessor, to replace all occurences of (for example) xyzzy_GCC_VERSION_plugh with something extracted from gcc --version.
That's going to be a lot of effort and maintenance load to do what probably isn't necessary anyway.
But, if you really want to do it, you could use something like:
actual=$(echo "GCC_VERSION" | gcc -E - | tail -1)
sed "s/xyzzy_GCC_VERSION_plugh/$actual/g" file1.c >file1_morphed.c
gcc -c -o file1.o file1_morphed.c
and your file1.c would contain at the top somewhere:
#if GCC_VERSION < 40503
#error Outdated compiler xyzzy_GCC_VERSION_plugh < 4.5.3
#endif
But, as i said, that's a fair bit of work for not much benefit. My advice is just to tell the person using your library how to get the compiler version themselves. They are developers after all, I'd expect them to be able to handle an instruction like that.
Combining the proposal of paxdiablo and ideas for static compile time assertions I settled for the following solution.
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#define ERROR_MESSAGE(major, minor, patchlevel) compiler_version__GCC_ ## major ## _ ## minor ## _ ## patchlevel ## __ ;
#define OUTDATED_COMPILER_ERROR(major, minor, patchlevel) ERROR_MESSAGE(major, minor, patchlevel)
#if GCC_VERSION < 40503
#error Outdated compiler version < 4.5.3
#error Absolute minimum recommended version is avr-gcc 4.5.3.
#error Use 'avr-gcc --version' from the command line to verify your compiler version.
#error Arduino 1.0.0 - 1.0.6 ship with outdated compilers.
#error Arduino 1.5.8 (avr-gcc 4.8.1) and above are recommended.
OUTDATED_COMPILER_ERROR(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
#endif
I have some C++0x code. I was able to reproduce it below. The code below works fine without -std=c++0x however i need it for my real code.
How do i include strdup in C++0x? with gcc 4.5.2
note i am using mingw. i tried including cstdlib, cstring, string.h and tried using std::. No luck.
>g++ -std=c++0x a.cpp
a.cpp: In function 'int main()':
a.cpp:4:11: error: 'strdup' was not declared in this scope
code:
#include <string.h>
int main()
{
strdup("");
return 0;
}
-std=gnu++0x (instead of -std=c++0x) does the trick for me; -D_GNU_SOURCE didn't work (I tried with a cross-compiler, but perhaps it works with other kinds of g++).
It appears that the default (no -std=... passed) is "GNU C++" and not "strict standard C++", so the flag for "don't change anything except for upgrading to C++11" is -std=gnu++0x, not -std=c++0x; the latter means "upgrade to C++11 and be stricter than by default".
strdup may not be included in the library you are linking against (you mentioned mingw). I'm not sure if it's in c++0x or not; I know it's not in earlier versions of C/C++ standards.
It's a very simple function, and you could just include it in your program (though it's not legal to call it simply "strdup" since all names beginning with "str" and a lowercase letter are reserved for implementation extensions.)
char *my_strdup(const char *str) {
size_t len = strlen(str);
char *x = (char *)malloc(len+1); /* 1 for the null terminator */
if(!x) return NULL; /* malloc could not allocate memory */
memcpy(x,str,len+1); /* copy the string into the new buffer */
return x;
}
This page explains that strdup is conforming, among others, to the POSIX and BSD standards, and that GNU extensions implement it. Maybe if you compile your code with "-D_GNU_SOURCE" it works?
EDIT: just to expand a bit, you probably do not need anything else than including cstring on a POSIX system. But you are using GCC on Windows, which is not POSIX, so you need the extra definition to enable strdup.
add this preprocessor "_CRT_NONSTDC_NO_DEPRECATE" to Project Properties->C/C++ Build->GCC C++ Compiler->Preprocessor->Tool Settings
Don't forget to check Preprocessor Only(-E)
This worked for me on windows mingw32.
I've been on a crusade lately to eliminate warnings from our code and have become more familiar with GCC warning flags (such as -Wall, -Wno-<warning to disable>, -fdiagnostics-show-option, etc.). However I haven't been able to figure out how to disable (or even control) linker warnings. The most common linker warning that I was getting is of the following form:
ld: warning: <some symbol> has different visibility (default) in
<path/to/library.a> and (hidden) in <path/to/my/class.o>
The reason I was getting this was because the library I was using was built using the default visibility while my application is built with hidden visibility. I've fixed this by rebuilding the library with hidden visibility.
My question though is: how would I suppress that warning if I wanted to? It's not something that I need to do now that I've figured out how to fix it but I'm still curious as to how you'd suppress that particular warning — or any linker warnings in general?
Using the -fdiagnostics-show-option for any of the C/C++/linker flags doesn't say where that warning comes from like with other compiler warnings.
Actually, you can't disable a GCC linker warning, as it's stored in a specific section of the binary library you're linking with. (The section is called .gnu.warning.symbol)
You can however mute it, like this (this is extracted from libc-symbols.h):
Without it:
#include <sys/stat.h>
int main()
{
lchmod("/path/to/whatever", 0666);
return 0;
}
Gives:
$ gcc a.c
/tmp/cc0TGjC8.o: in function « main »:
a.c:(.text+0xf): WARNING: lchmod is not implemented and will always fail
With disabling:
#include <sys/stat.h>
/* We want the .gnu.warning.SYMBOL section to be unallocated. */
#define __make_section_unallocated(section_string) \
__asm__ (".section " section_string "\n\t.previous");
/* When a reference to SYMBOL is encountered, the linker will emit a
warning message MSG. */
#define silent_warning(symbol) \
__make_section_unallocated (".gnu.warning." #symbol)
silent_warning(lchmod)
int main()
{
lchmod("/path/to/whatever", 0666);
return 0;
}
gives:
$ gcc a.c
/tmp/cc195eKj.o: in function « main »:
a.c:(.text+0xf): WARNING:
With hiding:
#include <sys/stat.h>
#define __hide_section_warning(section_string) \
__asm__ (".section " section_string "\n.string \"\rHello world! \"\n\t.previous");
/* If you want to hide the linker's output */
#define hide_warning(symbol) \
__hide_section_warning (".gnu.warning." #symbol)
hide_warning(lchmod)
int main()
{
lchmod("/path/to/whatever", 0666);
return 0;
}
gives:
$ gcc a.c
/tmp/cc195eKj.o: in function « main »:
Hello world!
Obviously, in that case, replace Hello world! either by multiple space or some advertisement for your wonderful project.
Unfortunately ld does not appear to have any intrinsic way of suppressing specific options. One thing that I found useful was limiting the number of duplicate warnings by passing -Wl,--warn-once to g++ (or you can pass --warn-once directly to ld).
A software I am working on ships with NETLIB BLAS/LAPACK embedded into its sources using all-lowercase symbol names but now while porting the application to windows I discovered that Intel MKL and several other BLAS/LAPACK implementations for this platform use all-uppercase symbol names. Is there a way to tell the gnu compiler/linker to ignore case while matching symbol names?
.
.
.
undefined reference to `_dgeqp3'
.
.
.
$ nm /lib/LAPACK.lib | grep -i " T _dgeqp3"
00000000 T _DGEQP3
The difference you're seeing is due to Fortran calling conventions: in Fortran, symbol case is unimportant, and thus every compiler has a way to translate Fortran symbol names into assembler symbol names: GNU compilers usually translate all to lowercase, Intel on Windows goes for uppercase.
If you're working with Fortran code, you can use the -fsymbol-case-upper option on the older g77 compiler (the newer gfortran compiler doesn't have this). Otherwise, no simple answer for C, except:
using #define's
using the C interfaces to BLAS and LAPACK.
I think you might be in for some trouble. Section 6.4.2.1 of the C spec says "Lowercase and uppercase letters are distinct" with respect to identifiers. That means that as far as your compiler and linker are concerned, _DGEQP3 and _dgeqp3 are different symbols. You can probably add some #define statements in a platform-specific header to line things up for you.
Is it because you're linking against a windows library rather than whatever you were using before that this bug showed up?
t.c
#define __CONCAT(x,y) x##y
#ifdef SUFFIX
#define __SUFFIX(x) __CONCAT(x,_)
#else
#define __SUFFIX(x) x
#endif
#ifdef UPPER
#define __c(U,l) __SUFFIX(U)
#else
#define __c(U,l) __SUFFIX(l)
#endif
#define xaxpy __c(XAXPY, xaxpy)
#include <stdio.h>
char* xaxpy;
char* DAXPY;
int main()
{
printf(xaxpy);
printf(DAXPY);
}
e.c
char* xaxpy = "ln";
char* xaxpy_ = "ls";
char* XAXPY = "UN";
char* XAXPY_ = "US";
there seems to be a way to introduce symbol aliases at link-time using --defsym:
Cetin#BAKA-CHAN ~
$ gcc -D UPPER -D SUFFIX -c t.c e.c
Cetin#BAKA-CHAN ~
$ gcc -o t t.o e.o -Wl,--defsym=_DAXPY=_xaxpy
Cetin#BAKA-CHAN ~
$ ./t
USln
Cetin#BAKA-CHAN ~
$
There must also be a way to give the linker different scripts to handle a large number of such symbol definitions. So I could make it part of the build process to automatically create linker scripts that create mappings between different cases.
In MSVC I have this in a header:
#define STR(x) #x
#define STR2(x) STR(x)
#define NOTE(text) message (__FILE__ "(" STR2(__LINE__) ") : -NOTE- " #text)
#define noteMacro(text) message (__FILE__ "(" STR2(__LINE__) ") : " STR2(text))
and I do
#pragma NOTE(my warning here)
GCC has:
#warning(my warning here)
However MSVC (2003) throws a fit when it sees #warning and gives "fatal error C1021: invalid preprocessor command 'warning'"
What can I do about this? Is there a way to have GCC recognize MSVC warnings or MSVC not throw an error on GCC warnings? Is there something I can do that works on both? I can have GCC warn me about unknown pragmas but that's not the most ideal solution.
The best solution I've found for this problem is to have the following in a common header:
// compiler_warning.h
#define STRINGISE_IMPL(x) #x
#define STRINGISE(x) STRINGISE_IMPL(x)
// Use: #pragma message WARN("My message")
#if _MSC_VER
# define FILE_LINE_LINK __FILE__ "(" STRINGISE(__LINE__) ") : "
# define WARN(exp) (FILE_LINE_LINK "WARNING: " exp)
#else//__GNUC__ - may need other defines for different compilers
# define WARN(exp) ("WARNING: " exp)
#endif
Then use
#pragma message WARN("your warning message here")
throughout the code instead of #warning
Under MSVC you'll get a message like this:
c:\programming\some_file.cpp(3) : WARNING: your warning message here
Under gcc you'll get:
c:\programming\some_file.cpp:25: note: #pragma message: WARNING: your warning message here
Not perfect, but a reasonable compromise.
As you have now discovered, #warning is not a standard feature, so you cannot use it with compilers that don't suppport it. If you want your code to work across platforms, you won't use #warning at all - or, at the least, not in code that MSVC is intended to process (it could be preprocessed out by #ifdef or equivalent). Hence:
#ifdef __GNUC__
#warning(warning message)
#else
#pragma NOTE(warning message)
#endif
But that repeats the message and I'm sure you had in mind not doing that - and it is bulky ; you'd only use it very seldom. You might also need to deal with other compilers than GCC (and I'm not familiar enough with MSVC to know how to identify it reliably).
It would be nice if #warning were standardized; it is not standardized in C99.
(There was, once upon a long time ago, an SO question about such features that could be added to C and #warning came up there.)
See also: Portability of #warning preprocessor directive
Guard them with #if statements. Look for a symbol that's defined by one compiler but not the other.
#ifdef _MSC_VER
#pragma NOTE(my warning here)
#else
#warning(my warning here)
#endif
Kind of ugly, but I don't see another way.
It is possible have code that works everywhere, and emits custom
warnings on many compilers, including most compilers people are likely
to use (GCC, clang, MSVC, Intel, ...).
First, we should distinguish between warnings and informational
messages. I think the only thing that makes sense is that, if you
compile with fatal warnings (e.g., -Werror on GCC), warnings
should cause compilation to fail, whereas informational messages
shouldn't.
As the original question mentions, MSVC 9.0+ supports
#pragma message("Hello")
Despite the (IMHO unfortunate) name, MSVC will emit a warinng here,
not an informational message. AFAICT there is no way to emit an
informational message.
GCC 4.8+ and Intel support warning message pragmas, which means we can
use the preprocessor to generate them:
#pragma GCC warning "Hello"
Note that, as of version 18, PGI does not support such warnings, even
though pgc++ masquerades as a version of GCC that should (i.e., it
sets __GNUC__, __GNUC_MINOR__, and __GNUC_PATCHLEVEL__ to values which
indicate GCC >= 4.8). They are
aware
of the issue. To get around this while still allowing some future
version of PGI which does support those to work properly, you can do
something like:
#if defined(__PGI)
# pragma diag_suppress 1675
#endif
Unfortunately I don't think there is a way to push/pop the warning
stack for PGI, so if you do this all subsequent unknown pragmas will
be silently ignored. Also, keep in mind that #pragma message is
silently ignored by PGI (it will not even generate a warning about the
pragma being unknown).
Clang also supports #pragma GCC warning (as well as #pragma clang
...), but as of 6.0 such warnings are actually informational (I've
filed a bug). I'm not sure when support was added, but clang's version
numbers are pretty useless anyways (thanks to Apple setting them to
something completely different in their clang
distribution). Unfortunately there is no __has_pragma feature test
macro, but we can temporarily disable the unknown pragma warnings so
that if the compiler doesn't support the pragma it will be silently
ignored instead of emitting an unwanted warning:
#if defined(__has_warning)
# if __has_warning("-Wunknown-pragmas")
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunknown-pragmas"
# pragma message "Hello"
# pragma clang warning "Hello"
# pragma clang diagnostic pop
# endif
#endif
Sure, it's ugly, but at least we can hide it behind a macro.
Cray 5.0+ also has a pragma for messages:
#pragma _CRI message "Hello"
I don't actually have access to Cray's compiler, so I can't be sure
about whether it is informational or a warning. If someone knows the
anwser, please comment!
Putting it all together, I recently added some macros to
Hedley to handle this, the current
version looks like this:
#if HEDLEY_HAS_WARNING("-Wunknown-pragmas")
# define HEDLEY_MESSAGE(msg) \
HEDLEY_DIAGNOSTIC_PUSH \
_Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \
HEDLEY_PRAGMA(message msg) \
HEDLEY_DIAGNOSTIC_POP
#elif \
HEDLEY_GNUC_VERSION_CHECK(4,4,0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0)
# define HEDLEY_MESSAGE(msg) HEDLEY_PRAGMA(message msg)
#elif HEDLEY_CRAY_VERSION_CHECK(5,0,0)
# DEFINE HEDLEY_MESSAGE(msg) HEDLEY_PRAGMA(_CRI message msg)
#else
# define HEDLEY_MESSAGE(msg)
#endif
#if HEDLEY_HAS_WARNING("-Wunknown-pragmas")
# define HEDLEY_WARNING(msg) \
HEDLEY_DIAGNOSTIC_PUSH \
_Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \
HEDLEY_PRAGMA(clang warning msg) \
HEDLEY_DIAGNOSTIC_POP
#elif \
(HEDLEY_GNUC_VERSION_CHECK(4,8,0) && !defined(__PGI)) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0)
# define HEDLEY_WARNING(msg) HEDLEY_PRAGMA(GCC warning msg)
#elif HEDLEY_MSVC_VERSION_CHECK(15,0,0)
# define HEDLEY_WARNING(msg) HEDLEY_PRAGMA(message(msg))
#else
# define HEDLEY_WARNING(msg) HEDLEY_MESSAGE(msg)
#endif
If you don't want to use Hedley (it's a single public domain / CC0 header for just this sort of thing) you can replace the internal macros without too much effort. If you do that, I'd suggest basing your port on the Hedley repo instead of this answer as I'm much more likely to keep it up to date.
If you wish, you can add to the above solutions a little thing (#pragma warning) before
your #pragma message:
#pragma warning()
#pragma message(" SOME USER WARNING - FILE LINE etc... ")
This little add-in generates real warning, and does not look bad in the window of VC.
For example:
1>e:\proj\file.h(19) : warning C4615: #pragma warning : unknown user warning type
1> SOME USER WARNING - FILE LINE etc...
1>proj - 0 error(s), 1 warning(s)
Usually I use this method to warnings were not too quiet, as in the case code without the #pragma warning().
For example, the form of warnings too quiet (for me of course).
1> SOME USER WARNING - FILE LINE etc..
1>proj - 0 error(s), 0 warning(s)
However, only a small cosmetics.