I need to compile a c++ (98. I cannot migrate yet to 11) code into a mex file.
Unfortunately after upgrading to Xcode 5.1 (which updated also Clang to 3.4 version) I cannot compile the code.
It is the same problem as in here: MEX compile error: unknown type name 'char16_t'
Unfortunately the accepted answer is to compile with c++11 support which I cannot do.
Reading in the source code of Clang I found these lines:
// In C11 these are environment macros. In C++11 they are only defined
// as part of <cuchar>. To prevent breakage when mixing C and C++
// code, define these macros unconditionally. We can define them
// unconditionally, as Clang always uses UTF-16 and UTF-32 for 16-bit
// and 32-bit character literals.
Builder.defineMacro("__STDC_UTF_16__", "1");
Builder.defineMacro("__STDC_UTF_32__", "1");
Now.. I wonder why if they define the macro they do not define the type char16_t.
And also... I cannot include (file not found) either cuchar (C++11) or uchar.h (C11)
Some idea on how to solve this problem?
EDIT: I'd like to understand if this is a bug of Clang (and I have to signal it) or not.
According to C++11 standard (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2018.html) the marco __STDC_UTF_16__ should be defined in the header file cuchar. But I cannot find that file. So because of that I would expect that the macro is undefined. I think the MEX include file relies on this fact.
Just define char16_t (maybe CHAR16_T) as a macro somewhere in your code.
#define char16_t uint16_t
Or, pass -DCHAR16_T=uint16_t flag at compile time.
Related
While trying to compile a simple range based for loop on MacOS Big Sur, I got this warning:
warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
I tried using clang++ and g++ but both gave the same warning. Is there a way to always compile with C++11 without having to use -std=c++11 and without using aliases?
Edit: The reason I would prefer not to use -std=c++11 is because I want the compiler to default to C++11 or higher.
To provide this question with a proper answer, based on the discussion in the comments:
Compilers such as GCC and Clang set the default in their source code and it cannot be changed by, e.g., modifying a config file. The only way to change the default would be to change it in the source code and to compile the compiler yourself. This is not worth it.
Furthermore, compilers change their default language from time to time, and setting another default, e.g. to C++11, will make all non-C++11 code require setting the language version explicitly.
Here's the key point: code and compilation options belong together. Do not rely on compiler defaults. Any serious project will use a build system (e.g. Make) which specifies how to compile the project.
Edit
For completeness sake, the default C++ version for GCC 10.2.0 is hardcoded in /gcc/c-family/c-opts.c:
/* Set C++ standard to C++17 if not specified on the command line. */
if (c_dialect_cxx ())
set_std_cxx17 (/*ISO*/false);
Question
Modern Fortran offers a few cross-platform mechanisms to record the compiler version and settings used to build an application. What methods does C++17 have to capture this information? The book by Horton and Van Weert, Beginning C++17, does not appear to address this question.
The Fortran tools are surveyed below.
1. Access to compiler versions and options
The iso_fortran_env in Fortran provides a standard way to access the compiler version and settings used to compile a code. A sample snippet follows.
Code sample
program check_compiler
use, intrinsic :: iso_fortran_env, only : compiler_options, compiler_version
implicit none
write ( *, 100 ) "compiler version = ", compiler_version ()
write ( *, 100 ) "compiler options = ", trim ( compiler_options () )
100 format ( A, A, / )
stop "normal termination . . ."
end program check_compiler
Sample output
$ gfortran -o check_compiler check_compiler.f08
$ ./check_compiler
compiler version = GCC version 8.0.0 20170604 (experimental)
compiler options = -fPIC -mmacosx-version-min=10.12.7 -mtune=core2
STOP normal termination . . .
2. Probing and interacting with host OS
Fortran commands like execute_command_line, get_command, and get_environment_variable offer another route to record information at compile time.
What methods does C++17 have to capture this information?
None. The C++ standard does not even recognize the concept of "compiler" or "options"; there is merely the "implementation".
Furthermore, it would not really make sense, as different C++ files linked into the same program can be compiled with different options. And I'm not just talking about DLL/SOs; you can in theory statically link files that were compiled with different options or even different compiler versions.
Different compilers have ways to specify what version they are through macros. But each one has its own way to report this.
Searching the C++20 standard draft, which is available in GitHub, I find no results for closely-localted "compiler" and "version", nor have I found something like this looking at the text of the standard.
C++20 is at this time still very close to C++17, and certainly such a mechanism has not been removed, so I think it's pretty safe to say that there's no such thing in C++20.
Each compiler injects their own preproxessor tokens indicating itmwas compiled by them, and what version. These tokens are cross platform on compilers that compile on and to kore than one platdorm, such as icc, gcx and clang.
There are now standard defined ways to detect the existence of some srd header files. Boost has extensive headers that decode compiler capabilities based of a myriad of techniques.
__cplusplus in theory is defined to the standard version, but compilers lie.
The language standard specifies macros __cplusplus that encode the version of the standard that the compiler claims to support. It expands to 201703L on a C++17 compiler, 201710L on a C++14 compiler, and so on. It might also define _STDC and _STDC_VERSION. Beyond that, everything is a vendor-specific extension that you should look up in your compiler's manual.
Some but not all compilers, including GCC and Clang, predefine a macro named __VERSION__ that expands to a string describing the compiler version. You can check for this with #ifdef. Beyond that, many compilers contain macros that expand to version numbers, which you can stringify and concatenate. However, be aware that some compilers treat these as compatibility tests, and will claim to be a different compiler if you ask. In addition to its own version numbers, Clang defines __GNUC__, __GNUC_VERSION__ and __GNUC_PATCHLEVEL__ to indicate its compatibility with GCC, and the Windows version will also define _MSC_VER, _MSC_FULL_VER and so on in its Microsoft-compatiblity mode.
You could therefore create a complicated set of nested #elif blocks to recognize various compilers' version macros, but it could never be complete or forward-compatible.
I am using QT Creator to make a C++ program on Ubuntu. The program I had written was compiling fine, until I decided to start using C++11 rather than C++98 (which is the default in QT Creator). I am using my own cmake file, rather than qmake, and so to do this, I included the following line in my CMakeLists.txt file:
set(CMAKE_CXX_FLAGS "-std=c++0x")
Now, part of my code has the following (which was not written by me):
#if (linux && (i386 || __x86_64__))
# include "Linux-x86/OniPlatformLinux-x86.h"
#elif (linux && __arm__)
# include "Linux-Arm/OniPlatformLinux-Arm.h"
#else
# error Unsupported Platform!
#endif
After transferring to C++11, I get an error at the line error Unsupported Platform!. This is because, from what I can see, the variable linux is not defined anywhere, although the variable __x86_64__ is defined.
Therefore, I have two questions:
1) Why is the variable linux not defined, even though I am using Linux?
2) How can I tell C++11 to ignore this error?
Thanks.
The identifier linux is not reserved. A conforming compiler may not predefine it as a macro. For example, this program:
int main() {
int linux = 0;
return linux;
}
is perfectly valid, and a conforming compiler must accept it. Predefining linux causes the declaration to be a syntax error.
Some older compilers (including the compiler you were using, with the options you were giving it) predefine certain symbols to provide information about the target platform -- including linux to indicate a Linux system. This convention goes back to early C compilers, written before there was a distinction between reserved and unreserved identifiers.
The identifier __linux__, since it starts with two underscores, is reserved for use by the implementation, so compilers are allowed to predefine it -- and compilers for Linux systems typically do predefine it as a macro expanding to 1.
Confirm that your compiler predefines __linux__, and then change your code so it tests __linux__ rather than linux. You should also find out what reserved symbol is used instead of i386 (likely __i386__).
Related: Why does the C preprocessor interpret the word "linux" as the constant "1"?
Change your standard-selection flag to -std=gnu++0x instead of c++0x. The gnu flavors provide some non-standard extensions, apparently including predefining the macro linux. Alternatively, check for __linux__ instead.
I'm building a project in C++ and I'm having some standard library issues.
When I use uint_t family types, the compiler shows an error message.
For example, when I declare a uint_8 type variable, it show an error in vim
uint8_t in namespace std does not name a type
does anyone know the problem?? (of course I included cstdint)
I tried stdint.h of C library and it works.
(though I actually want to use the standard C++ lib)
Ddditionally, the problem is that I have same problems with other c++ standard classes such as array`
And I use g++ version 4.8.2
The support of <cstdint> and <array> is added since C++11, add the flag -std=c++11 to g++, and it'll compile.
I have a project that correctly compiles and runs under g++ 4.8.1 and clang >= 3.3 in c++11 mode. However, when I switch to the experimental -std=c++1y mode, clang 3.3 (but not g++) chokes on the <cstdio> header that is indirectly included by way of Boost.Test (so I cannot easily change it myself)
// /usr/include/c++/4.8/cstdio
#include <stdio.h>
// Get rid of those macros defined in <stdio.h> in lieu of real functions.
// ...
#undef gets
// ...
namespace std
{
// ...
using ::gets; // <-- error with clang++ -std=c++1y
// ...
}
with the following error message:
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/cstdio:119:11:
error: no member named 'gets' in the global namespace
On this tutorial on how to set up a modern C++ environment, a similar lookup problem with max_align_t is encountered. The recommendation there is to use a sed script to surround the unknown symbols with #ifdef __clang__ macros, but that seems a fragile approach.
Setup: plain 64-bit Linux Mint 15 with
g++ (Ubuntu 4.8.1-2ubuntu1~13.04) 4.8.1
Ubuntu clang version 3.3-3~raring1 (branches/release_33) (based on
LLVM 3.3)
Questions:
what is causing this erorr? There is no __clang__ macro anywhere near the code in question, and clang in c++11 mode has no trouble at all.
Is it a language problem (does C++14 say something else than C++11 about importing C compatible symbols from the global into the std namespace)?
Do I need to change something with my include paths? (I use CMake to automatically select the header paths, and switch modes inside CMakeLists.txt)
Does clang have a switch to resolve this?
This note in the gets manpage looks relevant:
ISO C11 removes the specification of gets() from the C language, and since version 2.16, glibc header files don't expose the function declaration if the _ISOC11_SOURCE feature test macro is defined.
Probably should be
#if !_ISOC11_SOURCE
using ::gets;
#endif