How to enforce a header file at the forefront? - c++

Motivation:
I want to enable the memory detection of VC++, which requires that some statements must be at the forefront as follows:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
Question:
Suppose I have a header file forefront.h, what I want is the following effect:
a.cpp
#include <any_other_one.h>
#include <forefront.h> // An compiler error generated here!
b.cpp
#include <forefront.h> // OK
#include <any_other_one.h>
How to implement?

Create your own header file with the following contents:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
Now use the Forced Includes setting in the Advanced section of the project's settings. Any file specified there will be included before all others, in the order specified.

Since what you're really asking is how to ensure _CRTDBG_MAP_ALLOC is defined in all compilation units, use the VC++ project system to add that definition. Go to the project properties dialog, and in the C++ Preprocessor section add _CRTDBG_MAP_ALLOC to the Preprocessor Definitions line.

I think this is the most non-intrusive solution I come up with,
put the following at the beginning of forefront.h,
#if (__LINE__ != 0)
#error ERROR_FORE_FRONT_IS_NOT_THE_FIRST_TO_INCLUDE
#endif
you don't need to change others.h.
I tested this code with GCC 4.6.3.

I guess something like this might work:
other.h
#ifndef OTHER_H_
#define OTHER_H_
...
#endif
forefront.h
#ifdef OTHER_H_
#error Wrong include order
#endif

Related

Unexpected #else

For some reason I can't explain, the compiler is outputting an error saying that it found an unexpected #else token.
This occurs at the beginning of the file :
#if defined( _USING_MFC )
#include "stdafx.h"
#else
#include <windows.h>
#endif
There is nothing before that peice of code expect several (single-line) comments.
This error occurs in a .cpp file. What you see above is the beginning of the file. There is nothing before that.
I tried adding the following code before the code defined above, and the error is now an unexpected #endif
#if 1
#include "stdafx.h"
#endif
So I suspect there is an issue with the included stdafx.h file which contains the following code :
#ifndef STDAFX_H_INCLUDED
#define STDAFX_H_INCLUDED
#include <Afx.h>
#include <Windows.h>
using namespace ATL;
#endif // STDAFX_H_INCLUDED
There's really nothing special about it. I'm also including this stdafx.h file from a stdafx.cpp file that only contains the #include statement, and it compiles correctly.
Here are the project preprocessor definitions :
_DEBUG
_WIN32_WCE=$(CEVER)
UNDER_CE
WINCE
DEBUG
_WINDOWS
$(ARCHFAM)
$(_ARCHFAM_)
_UNICODE
UNICODE
_TERMINAL_FALCONX3_CE6
_NO_CPP_EXCEPTIONS
_DONT_INCLUDE_WS_HEADERS
_USING_MFC
And some extra informations :
Compiling for Windows CE 6 using Visual Studio 2008.
What would be causing this ? Thank you.
Based on the name stdafx, I assume it is a precompiled header.
A precompiler header must be the first include (preprocessor) directive in the file, you can't put anything (not even an ifdef) before it. The only exception being a few comment lines, as those would be ignore anyway.
Based on your example, you should put the #ifdef _USING_MFC into your stdafx.h, and include Afx.h there.

Can a macro redefinition be applied to single cpp file?

I'm using rapidjson, which is an all header library. In rapidjson.h, there is a macro RAPIDJSON_ASSERT, in one of my cpp files, I would like to redefine it, so I have this code at the top of my file:
#include "stdafx.h" // for windows
#pragma push_macro("RAPIDJSON_ASSERT")
#define RAPIDJSON_ASSERT(x) if(!(x)) throw std::logic_error("rapidjson exception");
#include "rapidjson/rapidjson.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
....
....
#pragma pop_macro("RAPIDJSON_ASSERT")
Here is the whay that rapidjson.h defines RAPIDJSON_ASSERT:
#ifndef RAPIDJSON_ASSERT
#include <cassert>
#define RAPIDJSON_ASSERT(x) assert(x)
#endif // RAPIDJSON_ASSERT
The documentation states that to override the RAPIDJSON_ASSERT logic, you just have to define RAPIDJSON_ASSERT before you include any of the files.
The issue is that when I run the code in the debugger, RAPIDJSON_ASSERT is not being redefined. I checked stdafx.h for anything which would include the rapidjson header files, and there isn't anything.
I was under the assumption that each compilation unit should run through the header files.
Note that if I move the redefinition of the macro into stdafx.h I get the macro redefined, but I was hoping to be able to do it per compilation unit.
It seems like you want to change the definition of RAPIDJSON_ASSERT for the rapidjson code itself
If so, you need to add a #define after the place where it is defined. Unless you want to edit the rapidjson.h file, the only alternative is to do this:
#include "stdafx.h" // for windows
// One would assume that the macro gets defined somewhere inside here
#include "rapidjson/rapidjson.h"
// Compiler will complain about macro redefinition without this #undef
#undef RAPIDJSON_ASSERT
#define RAPIDJSON_ASSERT(x) if(!(x)) throw std::logic_error("rapidjson exception");
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
Now the definition of RAPIDJSON_ASSERT is changed for the rest of the header files. You don't need the push_macro and pop_macro shenanigans - macros only are valid for each unit
Note that it's not a a good thing to redefine things for libraries using #define

How can I use the #error directive to provide the user pointers to useful information?

Suppose I have a file like the following
Mainfile.cpp
#include "stdafx.h"
#include <stdlib.h>
#include "Myfile.h"
#ifdef _MYFILE
#error Myfile.h to be included. Please refer Ream Me at C:\ReadMe
#endif
int _tmain(int argc, _TCHAR* argv[])
{
system("pause");
return 0;
}
Myfile.h
#pragma once
#undef _MYFILE
#define MYFILE
My goal is to provide additional information ("Please refer to ....") in case something is missing (MyFile.h was not included/found on the path).
How can I handle this with a third party library, like Boost? In this case, I don't have control on Boost and I cannot handle the definition of _MYFILE: then how can throw the error?
Pseudo code
#include "boost/boost.h"
#if (boost is not included || directory path is not set || boost .h file not found)
#error: Set boost path and compile again
#endif
It is impossible to do what you want in C/C++ code. Once you enter #include "myfile.h" it is up to compiler to locate that file and throw an error if it's nowhere to be found.
You are also misusing #ifndef ... #error ... #endif.
Some people use it to track header dependencies; imagine you have a header messages.h which requires header mytypes.h. Usually you just write something like this:
// File mytypes.h
#ifndef MYTYPES_H
#define MYTYPES_H
typedef unsigned char UINT8;
// ...
#endif
// File messages.h
#ifndef MESSAGES_H
#define MESSAGES_H
#include "mytypes.h"
// ...
#endif
But you can also write messages.h like that:
#ifndef MESSAGES_H
#define MESSAGES_H
#ifndef MYTYPES_H
#error I need mytypes.h to compile!
#endif
#endif
but it quickly becomes a chore to insert #errors for all the headers you depend on and then include those dependencies over and over again in all the source files where your header is needed. So in most cases first approach is the way to go.
You also need to decide what type of include guard you want to use. Don't #define MYFILE if you're already using #pragma once. Choose one and stick to it. (and remember that #pragma once is nonstandard).
Finally last but not least: if you really need to be that user friendly you will need to use your build system to verify that all extra libraries are installed and their headers are available. My guess is you're using Visual Studio's native builder. I don't know that one but I read it has pre-build actions so perhaps it's possible to define one which verifies boost location via some native visual studio calls or simply by running a batch file included in the project.
Shouldn't
#if _MYFILE
#error Myfile.h to be included. Please refer Ream Me at C:\ReadMe
#endif
be
#ifndef _MYFILE
#error Myfile.h to be included. Please refer Ream Me at C:\ReadMe
#endif

Multiple definition of several functions in two different .o files.

Basically I have lots of errors like these:
IMU/IMU.cpp.o: In function `MPU6050::dmpInitialize()':
Projects/Arduino/libraries/IMU/MPU6050_6Axis_MotionApps20.h:281: multiple definition of `MPU6050::dmpInitialize()'
Quadcopter.cpp.o:Projects/Arduino/libraries/IMU/MPU6050_6Axis_MotionApps20.h:281: first defined here
But im not sure how to solve this. I have lookes into several other similar questions but didnt fint any answer related to this code.
.ino
#include <Wire.h>
#include <IMU.h>
IMU imuController;
void setup() {
Wire.begin();
imuController.init();
}
IMU.h
#include "MPU6050_6Axis_MotionApps20.h"
MPU6050_6Axis_MotionApps20.h
#include "I2Cdev.h"
#include "helper_3dmath.h"
#include "MPU6050.h"
#include <avr/pgmspace.h>
MPU6050.h
#include "I2Cdev.h"
#include <avr/pgmspace.h>
It might be because you header file is included multiple times. What you can do is define guards like this:
#ifndef SOMEVAR - *make sure the file is included only once in the current scope*
#define SOMEVAR
//Symbol definitions
#endif
or you could include #pragma once in your header file, if your compiler supports it.
As W.B suggested, you need include guard for every header file you define.
Something like
Ex: Header.h
#ifndef HEADER_H
#define HEADER_H
// Header stuff in here...
#endif
This is 7 years way too late, but here's what I did
In my own mpu_sensor.h file, I only included
#ifndef MPU_SENSOR_H
#define MPU_SENSOR_H
#include "MPU6050.h"
#include "helper_3dmath.h"
....
#endif
Note that I don't MPU6050_6Axis_MotionApps20, since most datatypes are
In my mpu_sensor.cpp file, here's my includes:
#include "MPU6050_6Axis_MotionApps20.h"
#include "mpu_sensor.h"
Please note that MPU6050_6Axis_MotionApps20.h must be before my including my own header file.
It works now.
I agree that the library itself should be updated, but it seems like the author is not updating for the past few years.

How to check if MS compiler will compile my source code

Guys I was trying in VS to do something like:
#ifdef _MSC_VER
#include "stdafx.h"
#endif
but I'm getting an error telling me:
C1020: unexpected #endif
What is the correct way to do it?
Edit
/This is content of stdafx.h/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
//#include <stdio.h>
//#include <tchar.h>
#include <iostream>
using std::cout;
using std::cerr;
// TODO: reference additional headers your program requires here
You cannot put conditionals around stdafx.h because of the way MSVC precompiled headers work. It basically replaces everything once stdafx.h has been found (and usually requires #include "stdafx.h" to be the first line in the file) with the precompiled header contents, so it is as if you never wrote #if _MSC_VER and have an extra #endif.
Two solutions:
1) Do not use precompiled headers in your project. You can still use stdafx.h to include all the headers you require but compilation will be slow.
2) Put the conditional compile within the stdafx.h file.
(Taken from here)