C++ Macros #ifdef - c++

void testFunc();
int myval = 0;
int main()
{
int a = 1;
if (a > 0)
{
#define TEST1
testFunc();
#undef TEST1
}
int b = 2;
if ( b > 0)
{
#define TEST2
testFunc();
#undef TEST2
}
std::cout << "val : " << myval << endl;
getchar();
return 0;
}
void testFunc()
{
#ifdef TEST1
#define HERE 1
#endif
#ifdef TEST2
#define HERE 2
#endif
#ifdef HERE
myval = HERE;
#else
myval = -1;
#endif
}
How can I print the value of HERE to be 1 when testFunc() is called first time and then print the value of HERE to be 2 when it is called second time.
With the current code that I have, the value that is being printed is -1.

What you're missing is that the preprocessor directives evaluate before compile time.
That means that as the preprocessor parses your code it:
Sets TEST1
Unsets TEST1
Sets TEST2
Unsets TEST2
Checks if TEST1 is defined (it isn't)
Checks if TEST2 is defined (it isn't)
Checks if HERE is defined (it isn't)
That means testFunc becomes:
void testFunc() {
myval = -1;
}
And then, after this preprocessing, your code is compiled.
I would consider using something other than the preprocessor to accomplish what you are trying to achieve.

The way you intent to do it, it's not possible. Macros are a evaluted before compilation. It will simply parse the document from top to bottom and replace text according to the macros. When the pre-processing reaches testFunc, both TEST1 and TEST2 are not defined anymore (you #undef both earlier in the code), so you end up with
void testFunc()
{
myval = -1;
}
which is then compiled. It looks like you want to create something like a template function? Maybe actual function templates can solve your problem.

How can I print the value of HERE to be 1 when testFunc() is called first time and then print the value of HERE to be 2 when it is called second time.
This is what your attempted function looks like after pre-processing:
void testFunc()
{
myval = -1;
}
As you can see, the function doesn't take any form of input, and always unconditionally assigns the same value to the global variable.
You cannot achieve what you want with macros.
To have the behaviour of printing different value depending on how many times you call a function, you could use a function object instead. Function objects can have internal state:
auto testFunc = [HERE = 1]() mutable {
return HERE++;
};
std::cout << testFunc(); // prints 1
std::cout << testFunc(); // prints 2

All of # statements are called preprocessor directives. These are instructions to the compiler. You want the actually compiled code to maintain some state about the runtime of the program.
Two ways you could accomplish this are either using:
Global variable
Static variable
The following example shows both approaches. Each function also has a memory value which is updated to remember if the function has ever been called.
#include <iostream>
bool g_ran_already = false;
int first_different_global()
{
if (!g_ran_already)
{
g_ran_already = true;
return 1;
}
else
{
return 2;
}
}
int first_different_static()
{
static bool s_ran_already = false;
if(!s_ran_already)
{
s_ran_already = true;
return 1;
}
else
{
return 2;
}
}
int main(int argc, char** argv)
{
std::cout << "first_different_global() run 1: " << first_different_global() << "\n";
std::cout << "first_different_global() run 2: " << first_different_global() << "\n";
std::cout << "first_different_global() run 3: " << first_different_global() << "\n";
std::cout << "first_different_static() run 1: " << first_different_static() << "\n";
std::cout << "first_different_static() run 2: " << first_different_static() << "\n";
std::cout << "first_different_static() run 3: " << first_different_static() << "\n";
}
Output:
first_different_global() run 1: 1
first_different_global() run 2: 2
first_different_global() run 3: 2
first_different_static() run 1: 1
first_different_static() run 2: 2
first_different_static() run 3: 2

Related

How to get value from declaration only once?

Say I have a function that I want to call multiple times. At the start of this function I have declared an integer for a value of zero, and at the end of it I increased its value by one. Now I want to save the new value so when I call the function again the value of that variable becomes 2. Is there a way to do that besides getting the variable from another function or declare it at the top of line codes out of the functions?
TLDR
Yes, using the static keyword.
It changes the lifetime of the object declared with it, that becomes available for the whole duration of the program.
That said, you should be careful with using static local variables, because you're adding a state to the function execution.
#include <iostream>
using namespace std;
void printX()
{
static int x;
cout << "x: " << x << endl;
++x;
}
int main()
{
for (int i = 0; i < 10; ++i)
printX();
}
https://www.jdoodle.com/iembed/v0/909
There's more to the static keyword and you should look into it.
I'd suggest you read at least a couple of articles about it:
https://en.wikipedia.org/wiki/Static_(keyword)#Common_C
https://www.geeksforgeeks.org/static-variables-in-c/
you can use a static variable declared inside the function, since it is static the initialization to zero will happen only once and the rest of the time you call the function it will retain its value...
here is an example:
#include <iostream>
void foo(int x)
{
static int counter{0};
std::cout<< "this is x: " << x << std::endl;
counter++;
std::cout<< "this is counter: " << counter << std::endl;
}
int main() {
foo(1);
foo(10);
std::cout<< "something else in the app is executed... " << std::endl;
foo(101);
return 0;
}
and here the output:
this is x: 1
this is counter: 1
this is x: 10
this is counter: 2
something else in the app is executed...
this is x: 101
this is counter: 3

#define a Macro and Template that will run functions of any type, including void, and return an average run time?

Backstory
(You can skip. Useful if you want to expand and adopt my approach.)
I am trying to expand a debugging library I created to be able to do unintrusive benchmarking and debugging. So far, it looks something like this, however I am open to revamping. This is just similar to what I was using for doing type flexible debugging:
#define BENCH(FUNC,N)CT::bench(#FUNC,FUNC,N,__FILE__,__LINE__,__PRETTY_FUNCTION__)
// #FUNC is a string of the code for the function placed in the macro
// FUNC is the function. How it should be captured, I am not sure yet.
// N Should be the number of times you wish to run the captured function
// __FILE__, __LINE__, __PRETTY_FUNCTION__ are GCC predefined macros
// Used for easily locating the code that is generating the output.
template <typename First> // Problem: Ensure only functions used as arguments?
static First bench(const QString expression,
First &&type, // This is the type. Needed for the return.
quint64 repeatN, // Negative repeats make no sense.
const QString &_file,
const int &_line,
const QString &_pretty_function)
{
QString typeName = QConsoleToolkit::demangle(typeid(type).name());
int initial(-1); // Time required to execute function first time
int average(-1); // Average execution time.
for (int i=0; i < repeatN; i++) {
// *
// *
// No idea how to do this.
// Please help.
// *
// *
}
QTextStream(stdout)
<< "Benchmark: " << typeName
<< "\t" << expression
<< "\t" << _pretty_function
<< "\t" << _file
<< ":" << _line << endl
<< " Repeat: " << QString::number(repeatN) << endl
<< "Initial: " << QString::number(initial) << endl
<< "Average: " << QString::number(average) << endl;
// Unsure if this will work with void
return std::forward<First>(type);
}
// Returns string for type
QString CT::demangle(const QString &name)
{
int status;
std::unique_ptr<char, void(*)(void*)> res {
abi::__cxa_demangle(name.toLatin1(), NULL, NULL, &status),
std::free
};
return {(status==0) ? QLatin1String(res.get()) : name};
}
Actual Question
Take the following code:
void MyClass::foo()
{
//dostuff
}
QString MyClass::funString()
{
return "The quick brown fox jumps over the lazy dog";
}
void MyClass::bar()
{
BENCH(foo(), 1000);
QString s = BENCH(funString(),2000);
QTextStream(stdout) << s << endl;
}
My goal is to have MyClass::bar() output this: (Random numbers are made up for initial and average)
Benchmark: void foo() void MyClass::bar() /home/akiva/myclass.cpp:31
Repeat: 1000
Initial: 2523
Average: 1234
Benchmark: QString funString() void MyClass::bar() /home/akiva/myclass.cpp:32
Repeat: 2000
Initial: 5003
Average: 4025
The quick brown fox jumps over the lazy dog
Thus, how can I make it so the macro BENCH() can take any type of function, run it N times, benchmarking how long each iteration takes to run, and have it return the first initial value received upon initial run?
It can not be intrusive, thus making this line possible:
QString s = BENCH(funString(),2000);

What is the difference in printing a function with a static int with one std::cout and multiple std::cout?

So when I have this function, and I print it to the console via multiple statements, I get the expected results:
0
1
But when I print the function out through just one cout statement on the same line, I get:
3 2
(This is after the initial 0 and 1 that were previously printed)
Why does it print backwards?
#include "stdafx.h"
#include <iostream>
using namespace std;
int addOne()
{
static int s_num = -1;
return ++s_num;
}
int main()
{
cout << addOne() << "\n";
cout << addOne() << "\n";
cout << addOne() << " " << addOne() << "\n";
return 0;
}
You are actually stumbling on unspecified behavior. In this context, and any other such context where the operators are of the same precedence, the function calls can be evaluated in any order. In this case, the compiler chose to evaluate the second function call before the first, but other compilers might do it differently.

Class object (char) changes after function

I'm pretty new to C++, but this has got me stumped. I'm working on the base code for an RPG, but this one character in the class has got me stumped. I've isolated the pieces at issue here (there's a good 1000 lines cut out), and the problem remains.
Here's the class and header for the program:
#include <iostream>
#include <cstdlib>
using namespace std;
unsigned long errorcount;
// I know this is bad coding, but it's not going to be in the end product...
class character {
public:
void setgender(char newgender);
char getgender() const;
private:
char gender;
};
void character::setgender(char newgender) {
switch (newgender) {
case 'M': gender = 'M'; break;
case 'F': gender = 'F'; break;
default: gender = '0'; errorcount++; break;
}
std::cout << "\nDuring setgender function: " << gender;
return;
}
char character::getgender() const {
std::cout << "\nDuring getgender function: " << gender;
return gender;
}
This next part that has me scratching my head. I started the following code:
void PlayerCharacterCreation(character Player) {
string newgender;
while(true) {
std::cout << "\nAre you male or female?" << "\n1. Male" << "\n2. Female" << "\n::";
std::cin >> newgender;
if (newgender == "1") { Player.setgender('M'); break; }
if (newgender == "2") { Player.setgender('F'); break; }
std::cout << "\nInvalid response. Try again.";
}
std::cout << "\nAfter setgender function: " << Player.getgender();
}
void PlayerCreationTest() {
character Test;
PlayerCharacterCreation(Test);
char playergender = Test.getgender();
if (playergender != 'M' && playergender != 'F') { errorcount++; }
std::cout << "\nAfter getgender function: " << playergender;
std::cout << "\n\nOUTPUT BEGINS NOW\nGender: " << playergender << "\n";
std::cout << "OUTPUT ENDS. Total Errors: " << errorcount << ".";
return;
}
int main() {
PlayerCreationTest();
return 0;
}
Now as far as I can tell, there's nothing wrong with any of this - the (GCC) compiler doesn't complain, and it works just fine up to a point. But if I run it, I get the following output:
Are you male or female?
1. Male
2. Female
1
During setgender function: M
During getgender function: M
After setgender function: M
During getgender function: #
After getgender function: #
OUTPUT BEGINS NOW
Gender: #
OUTPUT ENDS. Total Errors: 1.
Worse than that, if I choose option "2" the output is the same only when it makes no sense:
Are you male or female?
1. Male
2. Female
2
During setgender function: F
During getgender function: F
After setgender function: F
During getgender function: #
After getgender function: #
OUTPUT BEGINS NOW
Gender: #
OUTPUT ENDS. Total Errors: 1.
In other words, the expected output goes badly wrong somewhere between the last line of PlayerCharacterCreation(), and the very next line of the PlayerCreationTest().
As far as I can tell, though, the "character" class should stay the same between functions, not change all willy-nilly like this.
I hope that's enough for someone to figure out what I'm doing wrong, but I was toying with it a little and managed to change the output character even more.
By adding an "srand(0)" line at the beginning of the main function, I can change the '#' to a 'y' for both options 1 and 2.
By adding a "GenderTest()" line at the beginning of the main function, I can change the '#' to a 'F', for both options. If I add both lines, only the one immediately above the "PlayerCreationTest()" line seems to matter. Which is odd, because the full code always returns an 'l' (lowercase L) instead of '#', and the main function is exactly the same as written above.
As far as I can tell, though, the "character" class should stay the same between functions, not change all willy-nilly like this.
Well, you're wrong. They do stay the same, because they are seperate variables. PlayerCharacterCreation creates a local character (a copy of Test), and at the end of the function, the object is destroyed.
The original character that you passed to PlayerCharacterCreation never changed, and you get some weird output because the gender was never set for that character.
The Player in PlayerCharacterCreation is a totally new character, it is not Test :)
If you want to modify the character passed to PlayerCharacterCreation, you have to pass it by reference (there are some other ways too, like passing a pointer, returning Player, but that's the best one):
void PlayerCharacterCreation(character& Player);
^^^
reference
void PlayerCharacterCreation(character Player)
Inside this function, Player is a local instance of character into which the calling parameter is copied. Consider the following:
#include <iostream>
void f1(int x) {
x++;
}
void f2(int i) {
i++;
}
int main() {
int i = 0;
f(i);
std::cout << i << '\n';
}
We know that the output from this will be '0', because f1::x and f2::i are their own independent variables copied from our source parameter.
If you want to pass a specific instance of a variable rather than a copy of it, you need to provide a pointer or a reference.
void by_pointer(Character* player) {
if (player == nullptr) {
error_handling();
}
player->do_thing();
}
by_pointer(&player);
void by_reference(Character& player) {
player.do_thing();
}
by_reference(player);
Example:
#include <iostream>
int f1(int& param) {
param++;
}
int main() {
int i = 0;
f1(i);
std::cout << i << '\n'; // outputs 1
}

Printing a pointer-to-member-field

I was debugging some code involving pointers to member fields, and i decided to print them out to see their values. I had a function returning a pointer to member:
#include <stdio.h>
struct test {int x, y, z;};
typedef int test::*ptr_to_member;
ptr_to_member select(int what)
{
switch (what) {
case 0: return &test::x;
case 1: return &test::y;
case 2: return &test::z;
default: return NULL;
}
}
I tried using cout:
#include <iostream>
int main()
{
std::cout << select(0) << " and " << select(3) << '\n';
}
I got 1 and 0. I thought the numbers indicated the position of the field inside the struct (that is, 1 is y and 0 is x), but no, the printed value is actually 1 for non-null pointer and 0 for null pointer. I guess this is a standard-compliant behavior (even though it's not helpful) - am i right? In addition, is it possible for a compliant c++ implementation to print always 0 for pointers-to-members? Or even an empty string?
And, finally, how can i print a pointer-to-member in a meaningful manner? I came up with two ugly ways:
printf("%d and %d\n", select(0), select(3)); // not 64-bit-compatible, i guess?
ptr_to_member temp1 = select(0); // have to declare temporary variables
ptr_to_member temp2 = select(3);
std::cout << *(int*)&temp1 << " and " << *(int*)&temp2 << '\n'; // UGLY!
Any better ways?
Pointers to members are not as simple as you may think. Their size changes from compiler to compiler and from class to class depending on whether the class has virtual methods or not and whether it has multiple inheritance or not. Assuming they are int sized is not the right way to go. What you can do is print them in hexadecimal:
void dumpByte(char i_byte)
{
std::cout << std::hex << static_cast<int>((i_byte & 0xf0) >> 4);
std::cout << std::hex << static_cast<int>(i_byte & 0x0f));
} // ()
template <typename T>
void dumpStuff(T* i_pStuff)
{
const char* pStuff = reinterpret_cast<const char*>(i_pStuff);
size_t size = sizeof(T);
while (size)
{
dumpByte(*pStuff);
++pStuff;
--size;
} // while
} // ()
However, I'm not sure how useful that information will be to you since you don't know what is the structure of the pointers and what each byte (or several bytes) mean.
Member pointers aren't ordinary pointers. The overloads you expect for << aren't in fact there.
If you don't mind some type punning, you can hack something up to print the actual values:
int main()
{
ptr_to_member a = select(0), b = select(1);
std::cout << *reinterpret_cast<uint32_t*>(&a) << " and "
<< *reinterpret_cast<uint32_t*>(&b) << " and "
<< sizeof(ptr_to_member) << '\n';
}
You can display the raw values of these pointer-to-members as follows:
#include <iostream>
struct test {int x, y, z;};
typedef int test::*ptr_to_member;
ptr_to_member select(int what)
{
switch (what) {
case 0: return &test::x;
case 1: return &test::y;
case 2: return &test::z;
default: return NULL;
}
}
int main()
{
ptr_to_member x = select(0) ;
ptr_to_member y = select(1) ;
ptr_to_member z = select(2) ;
std::cout << *(void**)&x << ", " << *(void**)&y << ", " << *(void**)&z << std::endl ;
}
You get warnings about breaking strict anti-aliasing rules (see this link), but the result is what you might expect:
0, 0x4, 0x8
Nevertheless, the compiler is free to implement pointer-to-member functionality however it likes, so you can't rely on these values being meaningful.
I think you should use printf to solve this problen
#include <stdio.h>
struct test{int x,y,z;}
int main(int argc, char* argv[])
{
printf("&test::x=%p\n", &test::x);
printf("&test::y=%p\n", &test::y);
printf("&test::z=%p\n", &test::z);
return 0;
}