I have a Qt/C++ project that uses Boost library, and I see Boost headers are included like this:
#ifndef Q_MOC_RUN
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#endif
I read that if you don't do this, MOC might cause problems.
The question is, shouldn't I then use this guard for including all other headers that definitely don't contain Q_OBJECT marco? Standard library headers for example, and other non-Qt libraries? Wouldn't it save a lot of time when MOC preprocessor runs?
From the topic Qt5 moc error in combination with boost:
First, this is a known MOC issue. The MOC can't expand some of the
macros used in the Boost library. I believe the reason Qt 4.8 works is
that a workaround for specific Boost macro definitions was added to
the MOC configuration for that version.
What you need to do to work around this issue: As stated above, use
Q_MOC_RUN to comment out problematic headers. You ONLY need to use
Q_MOC_RUN in files that produce a moc file (e.g. myheader.h will
produce moc_myheader.cpp). You can limit the hack to just those files.
So you don't need to #ifndef all usages of Boost headers in your
project which limits the pain of implementing this solution quite a
bit.
Seems this issue was fixed quite a long time ago, so whether you don't have any problems and don't need to support old versions of Qt, you may won't add this macro to your future code.
Related
According to this page, using Asio without Boost should be fairly straightforward, but I still cannot compile any file with an include that looks like any of these:
#include <asio>
#include <asio.hpp>
#include <asio/version.hpp>
I have set my compiler to use c++11 (which it was already doing, though I did switch from gnu++11 to c++11), and I have placed #define ASIO_STANDALONE before the various includes I am trying.
Is there some extra work necessary for accessing c++11 Asio headers beyond this? I just get file not found errors during compilation with any of the above attempts.
Asio can be used without Boost if the following conditions are met:
C++11 (or later) compiler in C++11 (or later) compile mode. Exactly how to enable this mode varies based on compiler. For GCC/clang use the -std=c++11 flag. For Xcode set the C++ language dialect to C++11 or later in project settings
Asio headers are downloaded from think-async.com. Asio is not part of the standard library (yet). It is bundled with Boost and is available standalone from the authors website. How exactly to add Asio to your include path varies based on compiler. For GCC/clang use -I/path/to/asio or place the Asio headers in /use/local/include. Xcode will also read /usr/local/include or you can specify a custom header path in the header search paths section of your project config.
#define ASIO_STANDALONE before including Asio headers. This define tells Asio to use the C++11 standard library features for things like error codes, shared pointers, etc rather than using Boost's polyfills.
I believe I understand the basics concerning precompiled headers and I can't think of any reason why a precompiled header couldn't be used inside a of library, but I've been told that it's either not possible or shouldn't be done (can't remember which).
I have a project where a shared library will be statically linked by multiple others and I would like to use precompiled headers inside the shared library for my external STL/Boost dependencies but I'm not sure if it's possible. I'm targeting OS X and Windows systems and common searches for details seem to point more towards Windows solutions involving stdafx.h which leads me to believe that using precompiled headers is customarily a Windows practice.
My question is simply this:
Can/should I use a precompiled header inside of a library that I'll be linking statically to other projects? If not, is using a convenience header for, say, all of my STL/Boost dependencies a good thing to pursue? I'm referring to something like this:
// common.h
#pragma once
#include <boost/this>
#include <boost/that>
#include <string>
#include <vector>
#include <other_stl_header>
// Foo.h
#include "common.h"
class Foo { ... }
// Foo.cpp
#include "Foo.h"
...
EDIT: I should specify, I have no expectation that the precompiled header be shared with anything other than the library I'm compiling. My question is related to whether or not it's possible to create a precompiled header that is used for the compilation of that library.
Once you have finished the compilation, there is no more usage for precompiled header and they have no effect on the linkage stage (that includes the shared library and any other linkable components). You can use it to speed up the compilation of your shared library but that's it, the static library is an outcome of the compilation, with or without precomiled headers usage.
A precompiled header is not an executable or any kind of linkable format. The compiler itself can define any kind of format for a precompiled haeder. Maybe it is simply tokenized, maybe some other includes and the definitions of other includes are already evaluated. The only intention for precompiled headers is a speed up for the compiler.
gcc also uses precompiled headers on demand but it is not a common practice to use this feature. gcc generates .gch files for the output of precompile stage.
The simple answer to your question: No
I'm working on a utility that needs to be able to compile on both standard C++ compilers and pre-standard compilers. The code can and will be thrown at just about any C++ compiler in existence.
I am looking for a means to robustly and portably determine whether the target compiler supports header files with or without an .h extension. I will also need to detect whether namespaces are supported. Both of these needs may or may not be possible.
A little background: The utility is the Inline::CPP language extension for Perl. The extension automatically includes <iostream>, and tries to make a good guess whether a '.h' is required or not (and of course whether or not the compiler supports namespaces). But it's far from perfect in that regard, and this issue is diminishing the breadth of the utility's usefulness.
So to reiterate the question: How do I portably detect whether a compiler supports standard headers such as <iostream>, or pre-standard headers such as <iostream.h>?
Not in the code, but in the build/configure system. For example in CMake, you could use try_compile and provide it a sample file.
...
try_compile(PRE_STANDARD_HEADERS tmp_builds pre_standard_headers_test.cpp)
if ( ${PRE_STANDARD_HEADERS} )
add_definitions( -D PRE_STANDARD_HEADERS )
endif()
You'd need to make that pre_standard_headers_test.cpp .. just a simple compilable exe that #include <iostream.h> for example.
Then in your normal code just an
#ifdef PRE_STANDARD_HEADERS
would do the trick.
The standard approach for Linux and other Unix-friendly platforms is to use a configure script. The script will generate as its output a Makefile and a config.h header file that turns on or off any compiler features that your code could rely on when available.
For Windows it is kind of expected that you will provide solution and project files for Visual Studio, with a pre-generated config.h header file.
Hey i've been following learncpp.com tuts for the last couple days, they say to comment out "#include "stdafx.h" from .cpp files for Code::Blocks.
Is that a must, to remove the include line? What happens if you had hundreds of files and changed from Visual Studio on Win7 to Code::Blocks on Linux or hand it off to someone else with a mac?
stdafx.h is the idiomatic name used for precompiled headers in the Visual Studio ecosystem. In a nutshell, it's a regular header, but the contents of this file will be compiled once and reused for all cpp files in the project.
That is useful since in most projects, a large number of headers (standard library, system header, shared project-wide definitions) are used by virtually all translation units (cpps), so using PCH is a huge performance benefit during compilation
(Actually, PCH is a hack to workaround C++' inefficient compilation and linkage model and it's a shame that we need to maintain it by hand … oups, blasphemy.)
But this also means that - as long as the contents of your stdafx.h are gcc-compatible - compilation with CodeBlocks should still work, but without the immediate performance benefit.
The stdafx.h generated by VS' app wizards doesn't work out of the box on other platforms - it typically includes Windows.h. So to make it work, guard the Windows-specific definitions with appropriate #ifdef/#endif pairs and vice versa for Linux or Mac-specific stuff.
No, that tutorial advice does not make any sense. stdafx.h does not break anything at all. The system of pre-compiled headers in Visual Studio compiler is intentionally designed that way.
If your compiler supports pre-compiled headers (and follows the same pre-compilation approach as Visual Studio), it can use stdafx.h for pre-compiling.
If your compiler does not support pre-compiled headers (or used a different pre-compilation approach), then stdafx.h is interpreted as an ordinary header file, no different from any other header file and processed the same way as any other header file.
It is possible that what is meant by that tutorial is that stdafx.h often includes some Windows-specific headers, not present on other platform. While it is possible, it really has nothing to do with stdafx.h itself at all. Obviously, if you are compiling your program on some other platform you should not attempt to include any Windows headers, regardless of how you are doing it: through stdafx.h or somewhere else.
As far as I'm aware stdafx.h is a Windows-only file (for precompiled headers): Your code will just fail to compile if you don't comment it out.
If you are not actually using a precompiled header (PCH), I advise going into Visual Studio's Options/Preferences->Precompiled Header and turning them off. If you try to remove them and still use Visual Studio, you will get a ton of errors.
The only thing to actually do is to include the path containing the stdafx.h (or precompiled header) in the default include path list. This is needed because the MS compiler actually replaces the #include "stdafx.h" with the precompiled data without really looking for the header.
Other compilers will usually want to pull in the data. But it should rather not be commented out. Usually you'll be able to tune your compiler to also make use of the precompiled header features to boost up compilation. With gcc that would be done with the -pch option. With Code Blocks I could find this wiki. Precompiled headers are not evil, on the contrary they will save you precious time if understood and used adequately.
I'm trying to use new C++0x features in Qt Creator under Windows (Qt Creator 2.0.1).
I read the thread Configuring the GCC compiler switches in Qt, Qt Creator, and QMake and added QMAKE_CXXFLAGS += -std=c++0x to .pro file.
After it Qt Creator gives me very strange errors on this simple code:
#include <memory>
int main()
{
}
Compiler errors:
'::swprintf' has not been declared
'::vswprintf' has not been declared
I try to compile my code from the command line with command g++ test.cpp --std=c++0x and get same error.
So what's wrong with Qt MinGW compiler? Is it possible to use C++0x features in Qt Creator?
First off, it could be that the library headers just don't represent their dependencies properly. Try adding an #include <cstdio> and perhaps (unfortunately) a using namespace std; to your file at the top.
Failing that, several people seem to have had issues with MinGW and swprintf. This mailing list post suggests adding this:
#ifdef WIN32
#define swprintf _snwprintf
#endif
See if that resolves the issue. (You want it at the very top of the file, too.)
If prepending random defines to your source seems like a bad idea to you, I suggest using -D build flags to conditionally inject the above define when you're building on MinGW.
See also this short discussion on the differences between swprintf on MinGW vs. other compilers.
Finally, failing all else, this link seems to attribute the problem to an issue with flags that enable __STRICT_ANSI__ in MinGW, and suggests commenting out a couple of lines in one of the MinGW headers to fix the issue. I would suggest adding a simpler #ifndef __STRICT_ANSI__ around them instead if you decide to go with this hack.