I'm trying to test gcc preprocessor for its macro expansion.
I write following code: (just for testing)
#include <stdio.h>
#define QUOTE "
#define TMPL hello
int main(){
printf(QUOTE TMPL QUOTE);
return 0;
}
the compiling result is:
$ gcc main.c -o main
main.c:3:15: warning: missing terminating " character
main.c: In function ‘main’:
main.c:7: error: missing terminating " character
main.c:7: error: missing terminating " character
main.c:7: error: ‘hello’ undeclared (first use in this function)
main.c:7: error: (Each undeclared identifier is reported only once
main.c:7: error: for each function it appears in.)
main.c:7: warning: format not a string literal and no format arguments
main.c:7: warning: format not a string literal and no format arguments
$
Then I try to have a look at the preprocessed result
$ gcc -E main.c -o tmp.c
main.c:3:15: warning: missing terminating " character
$
Though giving a warning, it somehow produces correct preprocessed code in tmp.c
int main(){
printf(" hello ");
return 0;
}
And I compiler tmp.c, hello is correctly printed.
I'm wondering why gcc -E could produce correct code, while using gcc compiling directly failed. Is there difference between the two method of gcc preprocessor?
$ gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
As I commented, a preprocessor macro should expand into a sequence of lexer tokens. Withing GCC source code, the libcpp (in charge of preprocessing and tokenizing) is producing a stream of tokens (not plain chars). A recent GCC 4.8, when run as gcc -Wall endyul.c -o endyl on your example, gives quite helpful diagnostics:
endyul.c:3:15: warning: missing terminating " character [enabled by default]
#define QUOTE "
^
endyul.c: In function 'main':
endyul.c:7:5: error: missing terminating " character
printf(QUOTE TMPL QUOTE);
^
endyul.c:7:5: error: missing terminating " character
endyul.c:4:14: error: 'hello' undeclared (first use in this function)
#define TMPL hello
^
endyul.c:7:18: note: in expansion of macro 'TMPL'
printf(QUOTE TMPL QUOTE);
^
endyul.c:4:14: note: each undeclared identifier is reported only once for each function it appears in
#define TMPL hello
^
endyul.c:7:18: note: in expansion of macro 'TMPL'
printf(QUOTE TMPL QUOTE);
^
Your GCC 4.2 is very old. You should consider upgrading it.
And clang (3.3) gives also a good diagnostic:
clang -Wall endyul.c -o endyul
endyul.c:3:15: warning: missing terminating '"' character [-Winvalid-pp-token]
#define QUOTE "
^
endyul.c:7:12: error: expected expression
printf(QUOTE TMPL QUOTE);
^
endyul.c:3:15: note: expanded from macro 'QUOTE'
1 warning and 1 error generated.
Read again the CPP manual of GCC, notably the chapters on Stringification and Concatenation.
Related
I'm new to C++ and read about curly bracket initializer which is available in C++ 11. I try to create a simple union which looks like this
union UExample {
UExample(const uint12_t value = 0) : raw{value} {}
uint12_t raw;
};
When I try to compile the file I get this error
./stack.h:18:57: error: expected member name or ';' after declaration specifiers
UBankedAddress(const uint12_t value = 0) : raw{value} {}
^
./stack.h:18:49: error: expected '('
UBankedAddress(const uint12_t value = 0) : raw{value} {}
^
./stack.h:18:55: error: expected ';' after expression
UBankedAddress(const uint12_t value = 0) : raw{value} {}
Dose anyone has an idea to solve this?
$ g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin20.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
I found a solution for this problem. It relates to the g++ compiler on MacOS. clang++ should be used instead.
Before (not working):
g++ stack.cpp -o stack
After (working):
clang++ -std=c++11 -stdlib=libc++ stack.cpp -o stack
I am trying to configure CMake to compile for OS X Target.This is IMac with OS X Yosemite v 10.10.2
Clang version:
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.1.0
When I compile without putting any compiler flags I am getting one error for this chunk of code in one the sources:
static const char* LogLevelStr[] {
"TRACE " ,
"INFO " ,
"WARNING" ,
"ERROR " ,
"FATAL " ,
};
error: definition of variable with array type needs an
explicit size or an initializer
I am compiling this code on Windows and GCC and it is completely fine so I don't understand why Clang complains here.So I decided,maybe I have to set C++11 support flags because I use this standard in the code a lot.
Setting
set (CMAKE_CXX_STANDARD 11)
or
set(CMAKE_CXX_FLAGS " -std=c++11")
Adds even more weird errors like these:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__bit_reference:51:52:
error:
expected ';' at end of declaration list
_LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT
^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__bit_reference:87:57:
error:
expected ';' at end of declaration swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT
^ >/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolc>hain/usr/bin/../include/c++/v1/__bit_reference:87:58:
error:
C++ requires a type specifier for all declarations >swap(__bit_reference<_Cp> __x, __bit_reference<_Cp> __y) _NOEXCEPT
^ >/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__config:338:21:
note:
expanded from macro '_NOEXCEPT'
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__bit_reference:89:10:
error:
expected '(' for function-style cast or type construction
bool __t = __x;
~~~~ ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__bit_reference:92:2:
error:
expected ';' after top level declarator } ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__bit_reference:1111:47:
error:
expected ';' at end of declaration list
_LIBCPP_INLINE_VISIBILITY __bit_iterator() _NOEXCEPT
The error block from above the compiler spits at the point it is trying to parse include
Now,I tried also to set:
set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++")
Same errors.
What do I miss here?
UPDATE:
I don't understand why some people marked this question for closing.Anyway,here is the problem in more details.I tried all those C++11 flags.I also added '=' to that static array.But most of the errors come after that.And it looks like root of those is .At the very first place where gets parsed it goes down into another class called __bit_reference and there at line 51 the compiler complains
on the following line
_LIBCPP_INLINE_VISIBILITY operator bool() const _NOEXCEPT
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/__bit_reference:51:52:
Expected ';' at end of declaration list
Most of the other errors are also in some ways connected to stl containers.
So my question is still valid.How do I get my source code to compile with the latest Clang on OS X including C++11 support.I am trying to do that with Xcode and have the same issues.
Xcode compiler output(some of it):
CompileC
/Users/michaeliv/Library/Developer/Xcode/DerivedData/xxxxxTest-hdkkzwyyppywsjgmoyuphranqtok/Build/Intermediates/xxxxxxTest.build/Debug/xxxxxxTest.build/Objects-normal/x86_64/XXXMath.o
/Users/XXXXXXX/Documents/XXXXX/xxxxxx/src/XXXMath.cpp normal x86_64
c++ com.apple.compilers.llvm.clang.1_0.compiler
cd /Users/xxxxxx/Desktop/xxxxTest
export LANG=en_US.US-ASCII
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
-x c++ -arch x86_64 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu++11 -stdlib=libc++ ....
It's difficult to say for sure since you aren't posting a reproducible problem.
However, the code sample you posted contains a flaw:
static const char* LogLevelStr[] {
"TRACE " ,
"INFO " ,
"WARNING" ,
"ERROR " ,
"FATAL " ,
};
should be changed to
static const char* LogLevelStr[] = {
"TRACE " ,
"INFO " ,
"WARNING" ,
"ERROR " ,
"FATAL " ,
};
I'm not 100% on this as regards the C++11 standard, however, this is my understanding.
When you write static const char* foo[] = { "foo", "bar", "baz", }; this is aggregate initialization and not list initialization or any other kind. In your code sample, it looks like you are trying to initialize an array using C++11 list-initialization. However, to my knowledge this is not possible, and the "brace-or-equal" syntax described in chapter 8 of the standard does not apply.
This answer refers to "clause 8" to argue that list-initialization of C-style arrays is not permitted by the standard: Initializing a member array in constructor initializer
IMO that is the problem and if I were you I would use an = there, even if it would be allowed to omit it in C++11 or some future standard.
const char* hi = "hi"; // ok
const char* hi2 = u8"hi"; // compile error
It causes
error: use of undeclared identifier 'u8'
My compiler supports C++ 11.
~/Project/cpp c++ -v
Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin15.0.0
Thread model: posix
Your compiler doesn't default to C++11 though.
[9:46pm][wlynch#watermelon /tmp] c++ -c blah.cc
blah.cc:2:19: error: use of undeclared identifier 'u8'
const char* hi2 = u8"hi"; // compile error
^
blah.cc:2:21: error: expected ';' after top level declarator
const char* hi2 = u8"hi"; // compile error
^
;
2 errors generated.
[9:47pm][wlynch#watermelon /tmp] c++ -c -std=c++11 blah.cc
[9:47pm][wlynch#watermelon /tmp]
I have the following code:
#include <type_traits>
int main()
{
}
g++ file.cc -std=c++0x
works just fine.
However, I need to use clang++ for some reason.
When I try
clang++ file.cc -std=c++0x
I get a bunch of errors:
In file included from file.cc:1:
In file included from /usr/include/c++/4.4.4/type_traits:50:
/usr/include/c++/4.4.4/tr1_impl/type_traits:230:41: error: expected ')'
struct is_function<_Res(_ArgTypes......)>
^
/usr/include/c++/4.4.4/tr1_impl/type_traits:230:28: note: to match this '('
struct is_function<_Res(_ArgTypes......)>
^
/usr/include/c++/4.4.4/tr1_impl/type_traits:230:12: error: redefinition of 'is_function<type-parameter-0-0 (type-parameter-0-1, ...)>'
struct is_function<_Res(_ArgTypes......)>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/4.4.4/tr1_impl/type_traits:227:12: note: previous definition is here
struct is_function<_Res(_ArgTypes...)>
^
/usr/include/c++/4.4.4/tr1_impl/type_traits:233:29: error: type qualifier is not allowed on this function
struct is_function<_Res(_ArgTypes...) const>
....
clang++ --version gives:
clang version 2.8 (branches/release_28)
Target: x86_64-redhat-linux-gnu
Thread model: posix
Any ideas how to fix that? (-std=c++11 doesn't work, not recognized.)
Clang 2.8 does not support C++11 features, you need to upgrade your compiler to use them.
I have some code I am maintaining that I've started compiling under clang 3.3.
When compiling with "-std=c++11", clang generates an error (given below). I've distilled the offending code to the following:
#include <stdio.h>
#define DBG_PRT(__format, ...) \
printf("%s:%d:%s: "__format, __FILE__, \
__LINE__, __FUNCTION__, ## __VA_ARGS__)
int main()
{
DBG_PRT("%s\n", "Hi");
}
This is clang's output:
test.cpp:10:5: error: no matching literal operator for call to
'operator "" __format' with arguments of types 'const char *' and
'unsigned int'
DBG_PRT("%s\n", "Hi");
^ test.cpp:4:29: note: expanded from macro 'DBG_PRT'
printf("%s:%d:%s: "__format, __FILE__, \
^ 1 error generated.
Without spaces between the string literal and "__format", it doesn't seem like the preprocessor should be able to expand __format. It clearly is, though, when not specifying -std=c++11. G++ 4.4.7 (with and without -std=c++0x) compiles just fine.
Is there an error with the compiler?
This is because ""_ is a syntax for user-defined string literals. Put a space in between to have the old behavior (concatenate literals). GCC works fine because 4.4.7 does not implement user defined literals (it appeared in version 4.7).
Also, as #Fred have pointed out, try to avoid using reserved identifier (double underscore).