I think this is child question but i can't find info how to solve it.
//*.h:
class Foo
{
#if defined(RedefChallangesCount)
static const mainDataType ChallangesCount = 500;
#undef RedefChallangesCount
#else
static const mainDataType ChallangesCount = 1;
#endif
...
int _correctAnswers[ChallangesCount];
....
}
In my VS tests class:
#include "stdafx.h"
#include "CppUnitTest.h"
#define RedefChallangesCount
#include "..\Core\ChallengeManager.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace Brans;
namespace CoreTests
{
TEST_CLASS(SomeTestClass)
{
public:
TEST_METHOD(SomeTestMethod)
{
Foo* cm = new Foo();
cm->Method();
...
delete cm;
}
}
}
It seems for me that i do all like in docs, but when run test with #define RedefChallangesCount line i got strange errors like "Access violation reading location", sometimes bad array
_correctAnswers. At the same time i see that ChallangesCount is 500 as expected. If i comment #define RedefChallangesCount line - all errors gone...
What can be wrong?
Your #undef makes me suspicious that this header is being included elsewhere (e.g by ChallengeManager.cpp, meaning you'll end up with your _correctAnswers having a size of 500 in some places and 1 in others, which would certainly explain your crash.
(edit): Are your tests a separate project in the solution, with the main code in its own project, or is your code all compiled directly in the test project?
To be safe, set your #define in the VS build configuration (for all projects being linked into the tests - you'll need to add a Tests build config for this, and use it instead of Debug/Release for the test build) rather than defining it in code, and remove the #undef
I tend not to have if defined sections within code, especially class code. I would tend to use a variable, and branch based on its value:
in the test class remove the #define RedefChallangesCount and replace with a global variable of bool RedefChallangesCount
Then your code becomes much simpler and can be as follows (simplified version for demonstration purposes):
#include <iostream>
using namespace std;
bool RedefChallangesCount = false;
int main()
{
int ChallangesCount;
cout << RedefChallangesCount << endl;
if (RedefChallangesCount)
ChallangesCount = 500;
else
ChallangesCount = 1;
cout << ChallangesCount << endl;
return 0;
}
as opposed to:
#if defined(RedefChallangesCount)
static const mainDataType ChallangesCount = 500;
#undef RedefChallangesCount
#else
static const mainDataType ChallangesCount = 1;
#endif
However, let me know if using preprocessor is a requirement and then I can try and sort you out a solution using that methodology, though as I said, I don't use preprocessor directives for actual program flow (have to add normally, as guaranteed I have done it once for a valid reason, and cant remember).
Related
I would like to make a macro-like object that can detect its use in the current scope and behave differently in such a case. For example, consider the following fragment of code
#define FOO /* expand to printf("first time\n"); or printf("not a first time\n"); */
{
FOO // prints "first time"
FOO // prints "not a first time"
{
FOO // prints "first time"
FOO // prints "not a first time"
}
FOO // prints "not a first time"
}
Is it possible to make this with macro or any other language element in C++?
For people curious why I need this: I would like to make an easily copy-pastable macro FOO that I can put everywhere to get time spent in code fragment between two occurrences of it.
For example:
FOO // initialize timer
// code fragment 1
FOO // print the time spent in code fragment 1
// code fragment 2
FOO // print the time spent in code fragment 2
// code fragment 3
FOO // print the time spent in code fragment 3
You can create a scoped timer class:
#include <chrono>
#include <iostream>
#include <thread>
class ScopedTimer {
using clock = std::chrono::steady_clock;
std::chrono::time_point<clock> _begin;
public:
ScopedTimer() : _begin{ clock::now() }
{}
ScopedTimer(ScopedTimer const&) = delete;
ScopedTimer& operator=(ScopedTimer const&) = delete;
void print_duration() {
using namespace std::chrono;
auto const duration = duration_cast<milliseconds>(clock::now() - _begin);
std::cout << "Duration: " << duration.count() << '\n';
}
};
int main() {
ScopedTimer timer{};
std::this_thread::sleep_for(std::chrono::seconds(1));
timer.print_duration();
std::this_thread::sleep_for(std::chrono::seconds(1));
timer.print_duration();
}
How about this one?
#define FOO(block) /* The code section to time */ \
do{ \
/* code for start of timing */ \
{ block } \
/* code for end of timing */ \
while(0); \
C Preprocessor macros are often discouraged. Although in your case, you are using them to reduce the repetition of printf("first time\n"); and reducing repetition in code is a good thing. Assuming that we only want to consider macro-based solutions, this is what I would do:
#define FOO_FIRST printf("first time\n");
#define FOO_ADDITIONAL printf("not a first time\n");
{
FOO_FIRST // prints "first time"
FOO_ADDITIONAL // prints "not a first time"
{
FOO_FIRST // prints "first time"
FOO_ADDITIONAL // prints "not a first time"
}
FOO_ADDITIONAL // prints "not a first time"
}
Your originally-posted solution was trying to use a single FOO for both FOO_FIRST and FOO_ADDITIONAL, as a "convenience" to the macro-user. My suggestion is to resist the urge to crease such a "convenience", because what it really does is hide the fact that it is doing something different depending on which expansion it is. Don't hide that fact from the macro-user -- in my opinion, it's not a good thing to have the macro-user using a macro "without thinking". Instead, programmers should be thinking about the effects of the code that they write, and the resultant code is more readable when the usage of two separate macro names makes it clear that the programmer is doing two separate actions.
Using macros to reduce repetition is justifiable; using macros to obscure the programmer's intent is something I wouldn't do.
In your reply to one of the other potential solutions, you indicated that you wanted a macro to have an effect something like a context-sensitive function that was named Initialize_Or_Print(). This fact is an indication that you are going down the wrong road. Programming constructs should have single, clear purposes. Whenever you start to get the feeling that you are needing to cram too many separate purposes into one construct (Initialize_Or_Print_Or_SpawnNewPlayer_Or_BoilWater() is the direction you're headed), it's probably a bad thing and should be factored into separate pieces.
#define FOO { if(!foo_check) std::cout << "first time" << std::endl; else std::cout << "not a first time" << std::endl; foo_check=!foo_check; };
pretty obvious, i'd say, with the caveat to define
bool foo_check=false;
at the right level, for example at the start of the function, at start of main or as global variable for a file scope.
Said so, I use a timer class as per #Ayxan Haqverdili answer.
You can make a macro that modifies each time. (at least in gcc and I believe in msvc too):
// (only tried in gcc)
#define FLIPFLOP (__COUNTER__ % 2)
#define FOO std::cout <<(!FLIPFLOP ? "flip\n":"flop\n");
#include <iostream>
int main()
{
FOO
FOO
FOO
FOO
}
but you can't by nature make the preprocessor depend on source code block scope, since what { or } actually means is only determined later by the parser. The preprocessor knows nothing about it.
There are various proposals for "compiletime programming" for example http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2320r0.pdf, but whether they will address this type of use, I don't really know
Building on ...an answer that was deleted while I was typing this. You can get the timer behavior you want via RAII and macro expansion:
BuildConfig.hpp
//...
#ifdef _DEBUG
# undef PROFILE_BUILD
#else
# define PROFILE_BUILD
#endif
#define TOKEN_PASTE_SIMPLE(x, y) x##y
#define TOKEN_PASTE(x, y) TOKEN_PASTE_SIMPLE(x, y)
#define TOKEN_STRINGIZE_SIMPLE(x) #x
#define TOKEN_STRINGIZE(x) TOKEN_STRINGIZE_SIMPLE(x)
//...
ProfileLogScope.hpp
#pragma once
#include <chrono>
#include <string>
class ProfileLogScope {
public:
explicit ProfileLogScope(const char* scopeName) noexcept;
~ProfileLogScope() noexcept;
ProfileLogScope() = delete;
ProfileLogScope(const ProfileLogScope&) = delete;
ProfileLogScope(ProfileLogScope&&) = delete;
ProfileLogScope& operator=(const ProfileLogScope&) = delete;
ProfileLogScope& operator=(ProfileLogScope&&) = delete;
protected:
private:
using time_point_t = std::chrono::time_point<std::chrono::steady_clock>;
const char* _scope_name = nullptr;
time_point_t _time_at_creation{};
};
#if defined PROFILE_LOG_SCOPE || defined PROFILE_LOG_SCOPE_FUNCTION
#undef PROFILE_LOG_SCOPE
#undef PROFILE_LOG_SCOPE_FUNCTION
#endif
#ifdef PROFILE_BUILD
#define PROFILE_LOG_SCOPE(tag_str) ProfileLogScope TOKEN_PASTE(plscope_, __LINE__)(tag_str)
#define PROFILE_LOG_SCOPE_FUNCTION() PROFILE_LOG_SCOPE(__FUNCSIG__)
#else
#define PROFILE_LOG_SCOPE(tag_str)
#define PROFILE_LOG_SCOPE_FUNCTION()
#endif
ProfileLogScope.cpp
#include "ProfileLogScope.hpp"
#include <iostream>
#include <ostream>
#include <iomanip>
#include <sstream>
ProfileLogScope::ProfileLogScope(const char* scopeName) noexcept
: _scope_name(scopeName)
, _time_at_creation(std::chrono::steady_clock::now()) {
/* DO NOTHING */
}
ProfileLogScope::~ProfileLogScope() noexcept {
const auto now = std::chrono::steady_clock::now();
const auto elapsedTime = (now - _time_at_creation);
std::cout << "ProfileLogScope " << _scope_name << " took " << elapsedTime.count() << " nanoseconds.\n";
}
Usage
void Foo();
int main() {
PROFILE_LOG_SCOPE_FUNCTION()
{
PROFILE_LOG_SCOPE("Algorithm 1");
}
Foo();
}
void Foo() {
PROFILE_LOG_SCOPE_FUNCTION();
//...
}
The macros expand to unique-per-line variable names and are no-ops when explicitly not in a profiling mode.
When C++20's std::source_location becomes available, this will become a lot less messy. See Jason Turner's video on the topic: https://www.youtube.com/watch?v=TAS85xmNDEc
I'm working on an application that includes this library, let's call Snap.h.
I found that compilation fails if Snap.h is not the last on the includes statements. And on closer look, I find this code in a header file included by Snap.h
#define Try try {
#define Catch } catch (PExcept Except){ErrNotify(Except->GetMsgStr());}
#define CatchFull } catch (PExcept Except){ErrNotify(Except->GetStr());}
#define CatchAll } catch (...){}
Basically this lets try and catch blocks to be used as statements, like so
Try;
<some code>
Catch;
You can see how this is an issue, these generic macros collide with other libraries very easily.
Unfortunately this is tens of thousands of lines of very complicated code and the application I'm working on is built around this library. Its not easily changed.
Cpp is not my strong suit, is there a way to limit the effects of macros in an include?
I not a big fan of #undef things, because you never now what other bad stuff can slumber in that big header. I prefer isolating it in a "compilation barrier" i.e. only including it in a separate wrapper translation unit, which only redefines and forwards what you need. In the following example Snap.h redefines BULLSHIT to std::terminate, but as you can try, main.cpp can use the function in Snap.h without its version of BULLSHIT:
/*! #file main.cpp
*/
#include <iostream>
#define BULLSHIT
#include "snap_wrapper.h"
int main() {
BULLSHIT
std::cout << wrapper::nice_function() << "\n";
}
/*! #file Snap.h
*/
#ifndef UNTITLED5_SNAP_H
#define UNTITLED5_SNAP_H
#define BULLSHIT std::terminate();
int nice_function() {
return 42;
}
#endif //UNTITLED5_SNAP_H
/*! #snap_wrapper.h
*/
#ifndef UNTITLED5_SNAP_WRAPPER_H
#define UNTITLED5_SNAP_WRAPPER_H
namespace wrapper{
int nice_function();
}
#endif //UNTITLED5_SNAP_WRAPPER_H
/*! #file snap_wrapper.c
*/
#include "snap_wrapper.h"
#include "Snap.h"
namespace wrapper {
int nice_function() {
return ::nice_function();
}
}
I am trying to implement a global variable that will be able to be used by different files and at the same time with std::array, but I get the following compiler error:
error: the value of ‘constants::HEIGHT’ is not usable in a constant expression
note: ‘constants::HEIGHT’ was not initialized with a constant expression
My code is split in the following files at the moment:
main.cpp
#include <iostream>
#include "classA.h"
#include "globals.h"
namespace constants {
extern const int WIDTH = 800;
extern const int HEIGHT = 600;
}
int main()
{
ClassA classA;
printf("Hello World");
std::cout << constants::WIDTH << " " << constants::HEIGHT << std::endl;
return 0;
}
classA.h
#include <array>
#include "globals.h"
class ClassA {
public:
std::array<int, constants::HEIGHT> m_arrayFixedRGBA;
ClassA();
};
classA.cpp
#include "classA.h"
ClassA::ClassA() {
}
globals.h
#ifndef CONSTANTS_H
#define CONSTANTS_H
namespace constants {
extern const int WIDTH;
extern const int HEIGHT;
}
#endif
I know that by removing extern, declaring the values in globals.h like this
#ifndef CONSTANTS_H
#define CONSTANTS_H
namespace constants {
const int WIDTH = 800;
const int HEIGHT = 600;
}
#endif
and removing the relevant lines in main.cpp, then the program is able to compile.
While this is simple (and fine for smaller programs), every time globals.h gets #included into a different code file, each of these variables is copied into the including code file. Therefore, if globals.h gets included into 20 different code files, each of these variables is duplicated 20 times. Header guards won’t stop this from happening, as they only prevent a header from being included more than once into a single including file, not from being included one time into multiple different code files. This duplication of variables isn’t really that much of a problem (since constants aren’t likely to be huge), but changing a single constant value would also require recompiling every file that includes the constants header, which can lead to lengthy rebuild times for larger projects.
What could be a work-around for this scenario?
You could define your constants as static constexpr members
// in some header file:
struct constants {
constexpr static int width = 800;
constexpr static int height = 600;
};
and use them like
std::array<int, constants::height> arr;
------ EDIT ------
Note that this approach only declares these compile-time constants, but does not define any variable. Thus there is no problem with multiple definitions confusing the linker (as with your implementation using extern variables).
However, before C++17 the opposite problem can occur: if you odr-use these constants, a link-time error will arise, as the linker cannot find a definition. For example the following code will fail
std::cout << constants::width << std::endl;
since operator(std::ostream&, something const&) takes the object to be written by reference. You can avoid this by either providing a definition somewhere (in a source file), or by avoiding such use, e.g.
std::cout << int(constants::width) << std::endl;
I'm trying to teach myself C++ (actually I should say re-learn, but I first learned it when I didn't know a thing about coding and year ago so it doesn't count) and I'm doing my first project after finishing the online tutorial. I figured since I had a good C# and VB.Net background I might as well try something a bit bigger, but not too big. Before I start, I'm using Code::Blocks as my IDE and the default compiler in that IDE (I believe it's MinGW). So here is my thing : I have a ChromaTest project (this is using the Razer Chroma SDK for those wondering about the name) which is a console app, and a ChromaTestDLL project, which is (you guessed it) a DLL (I decided to do a DLL to learn how to do so at the same time and because I might use some the code in a GUI project later on). Problem is I'm getting a Segmentation Fault error when trying to insert into a map. Here is the relevant code :
In the ChromaTestDLL Project
MyChroma.h (Header for the MyChroma class)
#ifndef MYCHROMA_H
#define MYCHROMA_H
#include <map>
#include <windef.h>
#include "RzChromaSDKTypes.h"
#include <string>
#include "Template.h"
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
using namespace std;
#ifdef __cplusplus
extern "C"
{
#endif
class DLL_EXPORT MyChroma
{
public:
MyChroma();
bool Init();
std::map<char, COLORREF> GetColorMapping();
void SetColorMapping(char key, COLORREF color);
void AssignToKeyBoard();
void SetColorFromString(string s, COLORREF color);
~MyChroma();
protected:
std::map<char, COLORREF>* _ColorMapping;
ChromaSDK::Keyboard::RZKEY KeyFromChar(char keyChar);
My_Chroma_Implementation* Chroma;
private:
};
#ifdef __cplusplus
}
#endif
#endif // MYCHROMA_H
MyChroma.cpp (Relevant implementation for MyChroma class)
#include "MyChroma.h"
#include "Template.h"
#include <iostream>
MyChroma::MyChroma()
{
_ColorMapping = new std::map<char, COLORREF>();
}
std::map<char, COLORREF> MyChroma::GetColorMapping() { return *_ColorMapping; }
void MyChroma::SetColorMapping(char key, COLORREF color){
if (_ColorMapping->count(key) == 0)
_ColorMapping->insert(std::make_pair(key, color)); //This where the error happens
else
(*_ColorMapping)[key] = color;
}
MyChroma::~MyChroma() {
delete Chroma;
delete _ColorMapping;
}
//Other implementations omitted
In the ChromaTest project
MyChroma.h (Header to import MyChroma class, slightly different from the one in ChromaTestDll, basically it only contains public members)
#ifndef MYCHROMA_H
#define MYCHROMA_H
#include <map>
#include <windef.h>
#include <string>
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
using namespace std;
#ifdef __cplusplus
extern "C"
{
#endif
class DLL_EXPORT MyChroma
{
public:
MyChroma();
bool Init();
std::map<char, COLORREF> GetColorMapping();
void SetColorMapping(char key, COLORREF color);
void AssignToKeyBoard();
void SetColorFromString(string s, COLORREF color);
~MyChroma();
};
#ifdef __cplusplus
}
#endif
#endif // MYCHROMA_H
Main.cpp (main app code)
#include <iostream>
#include "MyChroma.h"
#include <wingdi.h>
using namespace std;
int main()
{
MyChroma test = MyChroma();
bool result = test.Init();
cout << (result ? "Initialized\n" : "Failed to initialize Razer Chroma");
cout << "Setting color";
if (result){
test.SetColorMapping('a', RGB(255,0, 0)); //This call goes in the DLL where I said it failed earlier.
test.SetColorMapping('a', RGB(0,0,255));
}
return 0;
}
Sorry for the atrociously long code (please tell me if there are things I could have removed here). Can anybody spot any mistake in there I would not be surprised this would be linked to pointers, this is probably the concept which took me the most time to understand. At first I didn't put the map in a pointer and on the heap, but changing another variable to that earlier seemed to have fixed another problem so I figured I'd give it a try. Sadly I had pretty much the same errors when not putting the map on the heap too.
On a side note, can anybody explain to me what different between the heap and the stack, why would I want to go through the (risky) hassle of storing variables on the heap (with pointers and deletion and all) instead of on the stack, and when should I use the heap or when should I not.
Based on the information in your question:
The compiled code in your DLL appears to declare a MyChroma class containing a bunch of internal class members, in its header file.
Then your main application uses a completely different header file, that defines a class called MyChroma, stripped of its class members.
Then, your main application instantiates the MyChroma class, based on what it sees in its header files.
That's not going to work. Since your main application knows nothing about those class members, the actual class that it instantiates is too small.
And it instantiates a class on the stack.
And then the constructor comes from the DLL, which thinks the class contains all those other class members.
And the constructor in the DLL attempts to initialize them.
On the stack.
Hello stack corruption.
The answer here is simply "don't do what you did". This is undefined behavior. Everything that you compile that references a particular class must see an identical declaration (and inline method definitions) of the class.
Full stop.
No exceptions.
Well, with sufficient experience, it's possible to do something like this safely, when targetting a specific C++ implementation, but this is not the case here.
Until then, there are ways to hide the internal implementation details of library-provided classes, but this is not how you do it. The safe way to do it is with the PIMPL design pattern.
A few other thing you should not do, as well. This doesn't relate directly to the problem at hand, but this will avoid several other common pitfalls that can, without advance warning, pull the rug from under your feet:
Do not use use namespace std;. Especially in header files. Completely forget that something like that exists in the C++ language.
All your classes should also follow the Rule Of Three.
I came across a function today in a C++ file that included a #define macro.
The function ends with a return statement, which is followed by a #undef macro.
An example would be...
int test() {
#define STUFF()...
return 0;
#undef STUFF
}
Is this good or bad practice, and is there any advantage or disadvantage to doing this, or does the #undef need to be located before the return to be acknowledged?
Doing that is just fine, besides, the macro name may clash with another macro name. Hence you may use a ridiculous short name like 'A' or ridiculous long name like 'LIBRARY_LIBRARY_NAME_TEMPORARY_MACRO'
You should place the #undef right after the usage of the maco.
The #define and #undef are compiler directives. They are part of the preprocessing of the code and are ran independent of where they are put in relation of the "real" code.
Basically, before the compiler run your code it goes through every directive (#include, #define, #ifdef) and preprocesses your code, so, for example, when you do:
int firstVariable = MY_DIRECTIVE;
#define MY_DIRECTIVE 7
int doesNothing = 9;
int myVariable = MY_DIRECTIVE;
#undef MY_DIRECTIVE
int thirdVariable = MY_DIRECTIVE;
it transforms it in:
int firstVariable = MY_DIRECTIVE;
int doesNothing = 9;
int myVariable = 7;
int thirdVariable = MY_DIRECTIVE;
And only after it will compile your code (in this case giving you a error that MY_DIRECTIVE hadn't been defined on line 1 and 7)
For more info:
Preprocessor directives (cplusplus)
I would not call putting the content of a function by #defined akin to 'best practise'. As #IanMedeiros has indicated it is a pre-compiler directive which means when the compiler runs it has already been expanded. Its difficult to understand what the original author was thinking, but I would would consider a clearer approach which documents more of the authors reasoning with something like:
int test() {
#if defined(INCLUDE_STUFF)
Stuff()
#endif
)