This question already has answers here:
How can I detect g++ and MinGW in C++ preprocessor?
(2 answers)
Closed 7 years ago.
EDIT: Ha ha, search terms are a weird thing. I actually had to use the answer I got as a term for the search to finally find this question. In the spirit of StackOverflow, I'll vote to close my
own question as duplicate instead of deleting it, in case it'll serve as a landing point for
someone else.
I am writing several functions that are using asm, but I only want them to function when they're compiled with a compiler that can work with NASM. (I'm on C++11, by the way.)
I'm a little bit new to the whole concept of asm, but this is what I think I know:
GCC and its "relatives" (MinGW, TDM-GCC) use NASM, which is what I'm writing my functions for.
All Intel and AMD processors can theoretically understand NASM, regardless of operating system, because...
The X86/X64 assembler is determined by what the compiler implements.
Assuming the above is correct, what macro can I use to ensure that the functions I'm writing are defined if and only if I'm using a GCC (or similar) compiler, or a compiler that uses NASM? (The #ELSE would be a usable dummy version of the function to ensure general compatibility with other compilers.)
The only macros I know about of this sort relate to determining operating system (such as #IFDEF _WIN32), but that macro would incorrectly get used in the situations where I'm compiling with TDM-GCC or MinGW on Windows.
NOTE: In case anyone wonders, the functions in question are basically
"helpful, but not vital" utility functions. We don't have any plans to
compile with a non-GCC compiler, but it's open source code, so we want
to be considerate of others.
You can use the __GNUC__ macro to identify GCC (and some mostly compatible compilers like Clang and Intel's C++ compiler).
MinGW (any version) can be checking for __MINGW32__ and/or __MINGW64__.
Related
This question already has answers here:
Do all C++ compilers generate C code?
(5 answers)
Closed 8 years ago.
I have read that the original implementation of C++ by Bjarne Stroustrup was using a compiler named Cfront that converted C++ to C during the compilation process.
Is this still the case with modern compilers (most of them ?) ?
I couldn't find a good answer using Google (or I couldn't find the right search terms).
edit: This is not an exact duplicate because I'm asking for current/modern ones. But both questions & answers apply.
Absolutely not. The CFront way of doing things became untenable long ago. There are some C++ constructs with no C interpretation, especially exceptions, and stamping out literal C source for every template instantiation is a bit ridiculous. The entire reason Bjarne stopped making Cfront is because it was impossible.
It is, however, common to lower the code to a more useful IR like LLVM IR, and GCC also has an internal IR, before converting to machine code.
Short answer: no. Modern C++ compilers generate native code directly.
There's no reason why you can't compile C++ to C, there's just no real reason to do so either any more, so you're adding an extra stage in the compilation process that could just as easily not exist. However, there are still a couple of options if you really need C code output for some reason: the Comeau C++ compiler emits C code with the aim of porting your C++ to platforms where a C++ compiler may not exist (which these days, is very few), and Clang uses LLVM as a backend code generator, which has C as one of its many target instruction languages. (edit: of these options, the first is outdated and the second is no longer maintained)
In neither case does the C look anything like the code you put in: it's significantly less readable than machine code would be. The days of converting method calls to function calls with a this are certainly long gone - it's very much a case of "compiling" rather than "converting".
No, modern compilers, such as GCC and clang (and others based on LLVM) have generally two parts: back-end and front-end.
Front-end handles compiling source code language into some intermediate representaton, such as LLVM IR.
Back-end generates machine code on target platform, possibly using some optimisations from that intermediate form.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I check for C++11 support?
I am writing a small library and I would like to use class enums whenever the compiler supports them. I also want to use other C++11 features, such as final and override keywords.
So far, I have used tricks to make sure it compiled on all versions of GCC, but I when I booted my Windows partition, Visual Studio 2010 started complaining too. Here is an example of the tricks I used:
#if __GNUC__ == 4 && (__GNUC_MINOR__ > 7 || \
(__GNUC_MINOR__ == 7 && __GNUC_PATCHLEVEL__ > 1))
# define TATO_OVERRIDE override
# define TATO_NO_THROW nothrow
#else
# define TATO_OVERRIDE
# define TATO_NO_THROW throw()
#endif
I know that the newest version of Visual Studio already supports a batch of new features too. What I would like to have, is something like a set of macro which tells me what features are available on the compiler I am using.
#ifdef THIS_COMPILER_SUPPORTS_CLASS_ENUMS
...
#endif
Does this exist? Is there a library that does that?
The compiler’s documentation?
Let me clarify. I know how to find those information, my problem is elsewhere. I don’t want to go through every possible compiler’s documentation to gather those information, especially since the same compiler might support different features with respect to its version. This is what I have been doing so far, and what I am looking for is actually a way not to do that.
Boost actually has a wide range of such macros available. You could use that. Otherwise, the only way is to essentially check the compiler's version and use your knowledge of the features supported in that version to decide if a feature is available or not.
Essentially, what Boost does, except manually.
There were discussions of having some standardized feature test mechanism but it turns out that this doesn't make any sense: If a compiler implements the standard, all feature tests would yield true. If it doesn't there is no reason to assume that it follows the standard in terms of the feature tests!
Thus, using some sort of configuration file seems to be the most reliable approach. Personally, I would do it differently than explicitly checking for compiler versions: instead, I would use something trying whether a compiler supports a specific feature to an acceptable degree. The configuration could be run in terms of autoconf or something similar.
With respect to the resulting configuration I would try to map things to suitable constructs and not use conditional compilation outside the configuration headers. For example, I would use something like this:
#if defined(KUHL_HAS_CLASS_FINAL)
# define kuhl_class_final final
#else
# define kuhl_class_final
#endif
Specifically for class enums you might need to use something a bit tricky because the enumeration values will only be available within a scope while the values are only available outside a scope. Thus, it may be necessaray to come up with some form of extra nesting in one case but not the other.
clang has some built-in macros for various feature checks: clang feature-check macros
Would be nice if all compiler vendors would pick up these (and more).
“What I would like to have, is something like a set of macro which tells me what features are available on the compiler I am using.”
There's no such thing in the standard.
A practical approach to compiler differences is to have a header for each compiler and compiler version you support. These headers should have the same name. Which one is included depends on the include path, tool usage, which is easy to customize for each compiler.
I call that concept virtual headers. I've found that it works nicely for three levels: system dependency, compiler dependency and version dependency. I think the scheme doesn't scale up to more than that, but on the other hand, that seems to be all that one needs.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to find (and replace) all old C-style data type casts in my C++ source code?
I'm currently refactoring some old code and the project I am working on has a policy of only using the new c++ style casts. I'm trying to make sure that I don't miss any but currently the approach I'm taking is quite crude so I'm wondering if there is any way of making the old c style casts not compile in a c++ project? (or at least give a compiler warning if this is not possible)
If you use GCC, add -Wold-style-cast to the command line. That gives warnings, not errors, but you can always add -Werror, which turns warnings (all warnings) into errors.
As for other compilers, it seems no other compiler has such a warning option.
But that doesn't really matter: GCC is Free Software, and available on practically anything that can distinguish between zeros and ones. Just install it alongside your main compiler on your workstation, or into your continuous integration system, and use it for this task only. You will find that having two C++ compilers at hand is very convenient in general.
If installing GCC really isn't an option for you, you might want to take a peek at How to find (and replace) all old C-style data type casts in my C++ source code?, where some alternatives are discussed.
I recommend using this Perl script. Except for unusual conditions like
(void**)&b.ComInterfaceCall
it just appears to work.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
I have some C++ code. In the code there are many classes defined, their member functions, constructors, destructors for those classes, few template classes and lots of C++ stuff. Now I need to convert the source to plain C code.
I the have following questions:
Is there any tool to convert C++ code and header files to C code?
Will I have to do total rewrite of the code (I will have to remove the constructors,destructors and move that code into some init(), deinit() functions; change classes to structures, make existing member functions as function pointers in those newly defined structures and then invoke those functions using function pointers etc..)?
If I have to convert it manually myself, what C++ specific code-data constructs/semantics do I need to pay attention to while doing the conversion from C++ to C?
There is indeed such a tool, Comeau's C++ compiler. . It will generate C code which you can't manually maintain, but that's no problem. You'll maintain the C++ code, and just convert to C on the fly.
http://llvm.org/docs/FAQ.html#translatecxx
It handles some code, but will fail for more complex implementations as it hasn't been fully updated for some of the modern C++ conventions. So try compiling your code frequently until you get a feel for what's allowed.
Usage sytax from the command line is as follows for version 9.0.1:
clang -c CPPtoC.cpp -o CPPtoC.bc -emit-llvm
clang -march=c CPPtoC.bc -o CPPtoC.c
For older versions (unsure of transition version), use the following syntax:
llvm-g++ -c CPPtoC.cpp -o CPPtoC.bc -emit-llvm
llc -march=c CPPtoC.bc -o CPPtoC.c
Note that it creates a GNU flavor of C and not true ANSI C. You will want to test that this is useful for you before you invest too heavily in your code. For example, some embedded systems only accept ANSI C.
Also note that it generates functional but fairly unreadable code. I recommend commenting and maintain your C++ code and not worrying about the final C code.
EDIT : although official support of this functionality was removed, but users can still use this unofficial support from Julia language devs, to achieve mentioned above functionality.
While you can do OO in C (e.g. by adding a theType *this first parameter to methods, and manually handling something like vtables for polymorphism) this is never particularly satisfactory as a design, and will look ugly (even with some pre-processor hacks).
I would suggest at least looking at a re-design to compare how this would work out.
Overall a lot depends on the answer to the key question: if you have working C++ code, why do you want C instead?
Maybe good ol' cfront will do?
A compiler consists of two major blocks: the 'front end' and the 'back end'.
The front end of a compiler analyzes the source code and builds some form of a 'intermediary representation' of said source code which is much easier to analyze by a machine algorithm than is the source code (i.e. whereas the source code e.g. C++ is designed to help the human programmer to write code, the intermediary form is designed to help simplify the algorithm that analyzes said intermediary form easier).
The back end of a compiler takes the intermediary form and then converts it to a 'target language'.
Now, the target language for general-use compilers are assembler languages for various processors, but there's nothing to prohibit a compiler back end to produce code in some other language, for as long as said target language is (at least) as flexible as a general CPU assembler.
Now, as you can probably imagine, C is definitely as flexible as a CPU's assembler, such that a C++ to C compiler is really no problem to implement from a technical pov.
So you have: C++ ---frontEnd---> someIntermediaryForm ---backEnd---> C
You may want to check these guys out: http://www.edg.com/index.php?location=c_frontend
(the above link is just informative for what can be done, they license their front ends for tens of thousands of dollars)
PS
As far as i know, there is no such a C++ to C compiler by GNU, and this totally beats me (if i'm right about this). Because the C language is fairly small and it's internal mechanisms are fairly rudimentary, a C compiler requires something like one man-year work (i can tell you this first hand cause i wrote such a compiler myself may years ago, and it produces a [virtual] stack machine intermediary code), and being able to have a maintained, up-to-date C++ compiler while only having to write a C compiler once would be a great thing to have...
This is an old thread but apparently the C++ Faq has a section (Archived 2013 version) on this. This apparently will be updated if the author is contacted so this will probably be more up to date in the long run, but here is the current version:
Depends on what you mean. If you mean, Is it possible to convert C++ to readable and maintainable C-code? then sorry, the answer is No — C++ features don't directly map to C, plus the generated C code is not intended for humans to follow. If instead you mean, Are there compilers which convert C++ to C for the purpose of compiling onto a platform that yet doesn't have a C++ compiler? then you're in luck — keep reading.
A compiler which compiles C++ to C does full syntax and semantic checking on the program, and just happens to use C code as a way of generating object code. Such a compiler is not merely some kind of fancy macro processor. (And please don't email me claiming these are preprocessors — they are not — they are full compilers.) It is possible to implement all of the features of ISO Standard C++ by translation to C, and except for exception handling, it typically results in object code with efficiency comparable to that of the code generated by a conventional C++ compiler.
Here are some products that perform compilation to C:
Comeau Computing offers a compiler based on Edison Design Group's front end that outputs C code.
LLVM is a downloadable compiler that emits C code. See also here and here. Here is an example of C++ to C conversion via LLVM.
Cfront, the original implementation of C++, done by Bjarne Stroustrup and others at AT&T, generates C code. However it has two problems: it's been difficult to obtain a license since the mid 90s when it started going through a maze of ownership changes, and development ceased at that same time and so it doesn't get bug fixes and doesn't support any of the newer language features (e.g., exceptions, namespaces, RTTI, member templates).
Contrary to popular myth, as of this writing there is no version of g++ that translates C++ to C. Such a thing seems to be doable, but I am not aware that anyone has actually done it (yet).
Note that you typically need to specify the target platform's CPU, OS and C compiler so that the generated C code will be specifically targeted for this platform. This means: (a) you probably can't take the C code generated for platform X and compile it on platform Y; and (b) it'll be difficult to do the translation yourself — it'll probably be a lot cheaper/safer with one of these tools.
One more time: do not email me saying these are just preprocessors — they are not — they are compilers.
A program written in Visual C/C++ 2005/2008 might not compile with another compiler such as GNU C/C++ or vice-versa. For example when trying to reuse code, which uses windows.h, written for a particular compiler with another, what are the differences to be aware of?
Is there any information about how to produce code which is compatible with either one compiler or another e.g. with either GC/C++ or MSVC/C++? What problems will attempting to do this cause?
What about other compilers, such as LCC and Digital Mars?
The first thing to do when trying to compile code written for MSVC to other compilers is to compile it with Microsoft-extensions switched off. (Use the /Za flag, I think). That will smoke out lots of things which GCC and other compilers will complain about.
The next step is to make sure that Windows-specific APIs (MFC, Win32, etc.) are isolated in Windows-specific files, effectively partioning your code into "generic" and "windows-specific" modules.
Remember the argument that if you want your web page to work on different browsers, then you should write standards-compliant HTML?
Same goes for compilers.
At the language level, if your code compiles without warnings on GCC with -std=c89 (or -std=c++98 for C++), -pedantic -Wall, plus -Wextra if you're feeling brave, and as long as you haven't used any of the more blatant GNU extensions permitted by -pedantic (which are hard to do accidentally) then it has a good chance of working on most C89 compilers. C++ is a bit less certain, as you're potentially relying on how complete the target compiler's support is for the standard.
Writing correct C89 is somewhat restrictive (no // comments, declarations must precede statements in a block, no inline keyword, no stdint.h and hence no 64bit types, etc), but it's not too bad once you get used to it. If all you care about is GCC and MSVC, you can switch on some language features you know MSVC has. Otherwise you can write little "language abstraction" headers of your own. For instance, one which defines "inline" as "inline" on GCC and MSVC/C++, but "__inline" for MSVC/C. Or a MSVC stdint.h is easy enough to find or write.
I've written portable code successfully in the past - I was working mostly on one platform for a particular product, using GCC. I also wrote code that was for use on all platforms, including Windows XP and Mobile. I never compiled it for those platforms prior to running a "test build" on the build server, and I very rarely had any problems. I think I might have written bad code that triggered the 64bit compatibility warning once or twice.
The Windows programmers going the other way caused the occasional problem, mostly because their compiler was less pedantic than ours, so we saw warnings they didn't, rather than things that GCC didn't support at all. But fixing the warnings meant that when the code was later used on systems with more primitive compilers, it still worked.
At the library level, it's much more difficult. If you #include and use Windows APIs via windows.h, then obviously it's not going to work on linux, and the same if you use KDE with GCC and then try to compile with MSVC.
Strictly speaking that's a platform issue, not a compiler issue, but it amounts to the same thing. If you want to write portable code, you need an OS abstraction API, like POSIX (or a subset thereof) that all your targets support, and you need to be thinking "portable" when you write it in the first place. Taking code which makes heavy use of windows-specific APIs, and trying to get it to work on GCC/linux, is basically a complete rewrite AFIAK. You might be better off with WINE than trying to re-compile it.
You're mixing up "compilers" and "OSs". <windows.h> is not something that MSVC C compiler brings to the table: it's C-specific embodiment of Windows API. You can get it independently from Visual Studio. Any other C compiler on Windows is likely to provide it. On the Linux side, for example, you have <unistd.h>, <pthereads.h> and others. They are not an essential part of GCC, and any other compiler that compiles for Linux would provide them.
So you need to answer two different questions: how can I code C in such a way that any compiler accepts it? And how do I hide my dependencies on OS?
As you can tell from the diverse answers, this topic is fairly involved. Bearing that in mind here are some of the issues I faced when recently porting some code to target three platforms (msvc 8/Windows, gcc 4.2/Linux, gcc 3.4/embedded ARM9 processor). It was originally only compiling under Visual Studio 2005.
a) Much code that's written on the Windows platforms uses types defined in windows.h. I've had to create a "windows_types.h" file with the following in it:
#ifndef _WIN32
typedef short INT16;
typedef unsigned short UINT16;
typedef int INT32;
typedef unsigned int UINT32;
typedef unsigned char UCHAR;
typedef unsigned long long UINT64;
typedef long long INT64;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef void * HANDLE;
typedef long LONG;
#endif
Ugly, but much easier than modifying the code that, previously, was only targeting Windows.
b) The typename keyword was not required in templated code to declare types. MSVC is lax in this regard (though I assume certain compiler switches would have generated a warning). Had to add it in a number of places.
c) Simple, but time-consuming: Windows is not case sensitive and many #included files were specified with incorrect case causing problems under Linux.
d) There was a fair chunk of code using the Windows API for many things. An example was for CRITICAL_SECTIONS and INTERLOCKED_INCREMENT. We used the boost libraries as much as possible to replace these issues but reworking code is time-consuming.
e) A lot of the code relied on headers being included in precompiled headers. We had issues with using pch on gcc3.4 so we had to ensure that all .h/cpp files correctly included all their dependencies (as they should have in the first place).
f) VS 2005 has two nasty bugs. auto_ptr's can be assigned to anything and temporary variables are allowed to be passed to reference parameters. Both fail to compile (thankfully!) under gcc but rework is required.
g) Bizarrely, we had template code that was trying to explicitly specialise class template functions. Not allowed. Again gcc refused, VS 2005 let it go. Easy enough to rework into regular overloads once the problem is understood.
h) Under VS 2005 std::exception is allowed to be constructed with a string. Not allowed under gcc or the standard. Rework your code to prefer to use one of the derived exception classes.
Hopefully that's the kind of information you were looking for!
Well this is a quite difficult question. Fact is that MSVC does not support the newest
C standard, about it's c++ compliance I can tell you anyything. Howerver "windows" C is understand by both MSVC and gcc you just can not hope for the other way. E.g if you use ANSI C99 features then you might have a hard time "porting" from gcc to MSVC.
But as long as you try the way MSVC-> gcc you chances will be better. The only point you have to be aware of is the libraries. Most of the libraries on Windows are supposed to work with MSVC and so you need some extra tools to make them accessible to gcc also.
LCC is a quite older system,which AFAIKT does not support much from ANSI C99, it also needs tools from MSVC to work properly. LCC is "just " a compiler.
lcc-win32 is a C Development system striving to be ANSI C99 compliant. It comes along with linker, IDE etc.
I can not tell about the state of Digital Mars implementation
Then there is also Pelles-C which is a fully fledged IDE also.
And we have hanging around OpenWatcom. Which once was quite a decent system but I can't tell how conformant it is.
All in all the "best" you can hope for the easier way from MSVC -> other system but it will probably be much worse the other way round.
Regards
Friedrich
vs2008 is a lot more standards compliant than 2005.
I have had more problems going the other way, especially the 'feature' of gcc that lets you allocate an array with a variable size at run time "int array[variable]" which is just pure evil.
A program written in Visual C/C++ 2005/2008 might not compile with another compiler such as GNU C/C++ or vice-versa.
This is true if you either (1) use some sort of extension available in one compiler but not another (the C++ standard, for instance requires the typename and template keywords in a few places but many compilers -- including Visual C++ don't enforce this; gcc used to not enforce this either, but changed in 3.4) or (2) use some standard compliant behavior implemented on one compiler but not another (right now the poster boy for this is exported templates, but only one or two compilers support this, and Visual C++ and gcc are not in that group).
For example when trying to reuse code, which uses windows.h, written for a particular compiler with another,
I've never seen a problem doing this. I have seen a problem using Microsoft's windows.h in gcc. But when I use gcc's windows.h in gcc and Microsoft's windows.h in Visual C++ I have access to all of the documented functions. That's the definitions of "implemented windows.h" after all.
what are the differences to be aware of?
The main one I've seen is people not knowing about the dependent template/typename thing mentioned above. I find it funny that a number of people think gcc is not smart enough to do what Visual C++ does, when in reality gcc had the feature first and then decided to remove it in the name of standards compliance.
In the near future you will run into problems using C++0x features. But both gcc and Visual C++ have implemented the easier things in that standard.