Using pointers to members and macros - c++

I'm having problems with the following code:
#include<iostream>
#include<utility>
#define Row *prow
#define Col *pcol
typedef unsigned int uint;
typedef std::pair<uint, uint> Node;
uint Node::Row = &Node::first;
uint Node::Col = &Node::second;
int main()
{
Node node(1,2);
std::cout << node.*prow << node.*pcol << '\n'; // OK
std::cout << node.Row << node.Col << '\n'; // doesn't compile
}
The idea was to use std::pair but replace first and second with other names, in that case Row and Col. However, the last line doesn't compile even though it should be exactly the same as the line before it. I'd really appreciate if someone could explain me why it happens. I'm using VS2015.
Edit: compiler error C2059 syntax error:'*'

.* is a single token. Your macro is generating two adjacent tokens, . and *, which is not the same thing. (Or at least it might do. Almost certainly you're invoking undefined behaviour.)
There's probably a solution involving token pasting, but you'd do yourself a big favour (and make Bjarne happy) by just not using macros in C++.

Related

Change variable type inside main() C++

I have this code , i need output x variable as double (3.14) without changing anything in the main function
#include <iostream>
int main() {
int x = 3.14;
std::cout << x << "\n";
return 0;
}
What should i do ?
There are two solutions, one correct and one your professor probably wants.
The correct solution (one method, there are other similar ones).
Add this right after the #include line:
int main() {
double x = 3.14;
std::cout << x << "\n";
return 0;
}
#if 0
Add this at the end of the file:
#endif
The incorrect solution for your professor.
Add this line before main:
#define int double
Why is this incorrect? Because #defineing a reserved word is undefined behaviour.
[macro.names] A translation unit shall not #define or #undef names lexically identical to keywords [...]
Why do I think your professor probably wants this? Because I've seen a few C++ assignments, and observed that their authors all too often disregard and abuse the C++ standard.
Your professor might want the first solution instead. I have no way to predict that.

Cast an object value without pointers

Let's assume that A and B are two classes (or structures) having no inheritance relationships (thus, object slicing cannot work). I also have an object b of the type B. I would like to interpret its binary value as a value of type A:
A a = b;
I could use reinterpret_cast, but I would need to use pointers:
A a = reinterpret_cast<A>(b); // error: invalid cast
A a = *reinterpret_cast<A *>(&b); // correct [EDIT: see *footnote]
Is there a more compact way (without pointers) that does the same? (Including the case where sizeof(A) != sizeof(B))
Example of code that works using pointers: [EDIT: see *footnote]
#include <iostream>
using namespace std;
struct C {
int i;
string s;
};
struct S {
unsigned char data[sizeof(C)];
};
int main() {
C c;
c.i = 4;
c.s = "this is a string";
S s = *reinterpret_cast<S *>(&c);
C s1 = *reinterpret_cast<C *>(&s);
cout << s1.i << " " << s1.s << endl;
cout << reinterpret_cast<C *>(&s)->i << endl;
return 0;
}
*footnote: It worked when I tried it, but it is actually an undefined behavior (which means that it may work or not) - see comments below
No. I think there's nothing in the C++ syntax that allows you to implicitly ignore types. First, that's against the notion of static typing. Second, C++ lacks standardization at binary level. So, whatever you do to trick the compiler about the types you're using might be specific to a compiler implementation.
That being said, if you really wanna do it, you should check how your compiler's data alignment/padding works (i.e.: struct padding in c++) and if there's a way to control it (i.e.: What is the meaning of "__attribute__((packed, aligned(4))) "). If you're planning to do this across compilers (i.e.: with data transmitted across the network), then you should be extra careful. There are also platform issues, like different addressing models and endianness.
Yes, you can do it without a pointer:
A a = reinterpret_cast<A &>(b); // note the '&'
Note that this may be undefined behaviour. Check out the exact conditions at http://en.cppreference.com/w/cpp/language/reinterpret_cast

C++ initialization of vector of structs

I am trying to make a keyword-recognizing subroutine under OSX Yosemite, see the listing below. I do have a couple of strange things.
I am using the "playground" for making MWE, and the project builds seemingly OK, but does not want to run:
"My Mac runs OS X 10.10.5, which is lower than String sort's minimum deployment target."
I do not understand even the message, and especially not what my code makes with sorting?
Then, I pasted the relevant code to my app, where the project was generated using CMake, and the same compiler, and the same IDE, in the same configuration presents with the message
"Non-aggregate type 'vector cannot be initialized with an initializer list"
in the "vector QInstructions={..}" construction.
When searching for similar error messages, I found several similar questions, and the suggested solutions use default constructor, manual initialization, and the like. I wonder if standard-resistant compact initialization is possible?
#include <iostream>
using namespace std;
#include <vector>
enum KeyCode {QNONE=-1,
QKey1=100, QKey2
};
struct QKeys
{ /** The code command code*/
std::string Instr; ///< The command string
unsigned int Length; ///< The significant length
KeyCode Code; //
};
vector<QKeys> QInstructions={
{"QKey1",6,QKey1},
{"QKey2",5,QKey2}
};
KeyCode FindCode(string Key)
{
unsigned index = (unsigned int)-1;
for(unsigned int i=0; i<QInstructions.size(); i++)
if(strncmp(Key.c_str(),QInstructions[i].Instr.c_str(),QInstructions[i].Length)==0)
{
index = i;
cout << QInstructions[i].Instr << " " <<QInstructions[i].Length << " " << QInstructions[i].Code << endl;
return QInstructions[i].Code;
break;
}
return QNONE;
}
int main(int argc, const char * argv[]) {
string Key = "QKey2";
cout << FindCode(Key);
}
In your code
vector<QKeys> QInstructions={
("QKey1",6,QKey1),
{"QKey2",5,QKey2}
};
the first line of data is using parenthesis "()". Replace them with accolades "{}" and it will work.
Also, i see you have written unsigned index = (unsigned int)-1;. This is undefined behavior according to the standard. This is also bad because you are using a C-style cast (see here). You should replace it with:
unsigned index = std::numeric_limits<unsigned int>::max();
Finally, I found the right solution as
Initialize a vector of customizable structs within an header file . Unfortunately, replacing parenthesis did not help.
Concerning setting an unsigned int to its highest possible value using -1, I find as overkill to use std::numeric_limits<unsigned int>::max() for such a case, a kind of over-standardization. I personally think that as long as we are using two's complement representation, the assignment will be correct. For example, at
http://www.cplusplus.com/reference/string/string/npos/
you may read:
static const size_t npos = -1;
...
npos is a static member constant value with the greatest possible
value for an element of type size_t.
...
This constant is defined with a value of -1, which because size_t is
an unsigned integral type, it is the largest possible representable
value for this type.

How to find out if the name of the identifier is an array?

I am exploring some programs which contain thousands of lines in them over a range of files with almost as many variables and pointers in them.
Whenever i encounter a variable, i have to trace it backwards in all the files to check whether its a simple pointer or an array, causing utter inconvenience.
Is there a way that i make a function that tells me if there are more than one memory blocks associated with that pointer?
Or is there a built in function for that, just giving binary answer..!!!
The short answer is no -- it's hard to tell even at run-time whether a pointer is to an array or not.
If you use a good IDE, that will likely let you hover over a variable name and show you the deinition, which in lot of cases will give you the answer you're after.
I use Eclipse, which I find to be pretty good at telling me the types of variables. Others will use other IDES; YMMV.
This piece of code may help you.
‎#include <iostream>
using namespace std;
typedef char true_type;
typedef struct{ char one; char two;} false_type;
template <size_t N, typename T>
true_type test_func( T (&anarr)[N]);
false_type test_func( ... );
{
template <typename T>
bool is_an_array( const T& a) // const reference is important !!
if (sizeof (test_func(a)) == sizeof(true_type) ) return true;
else return false;
}
int main()
{
char testarr[10] = {'a','b','c','d','e','f','g','h','i','j'};
if (is_an_array(testarr) ) cout << "testarr is an array" << endl; else cout <<
"testarr is not an array" << endl;
char a_char = 'R';
if (is_an_array(a_char)) cout << "a_char is an array" << endl; else cout << "a_char is
not an array" << endl;
}
You could try with a cross-referencing tool. There's a chance that its parser is dumb enough not to be hampered by errors as much as a full-fledged IDE. Source Navigator is one with which I played a little years ago.

C++ Getting the size of a type in a macro conditional

Is there some way to do something like this in c++, it seems sizeof cant be used there for some reason?
#if sizeof(wchar_t) != 2
#error "wchar_t is expected to be a 16 bit type."
#endif
No, this can't be done because all macro expansion (#... things) is done in the pre-processor step which does not know anything about the types of the C++ code and even does not need to know anything about the language!
It just expands/checks the #... things and nothing else!
There are some other common errors, for example:
enum XY
{
MY_CONST = 7,
};
#if MY_CONST == 7
// This code will NEVER be compiled because the pre-processor does not know anything about your enum!
#endif //
You can only access and use things in #if that are defined via command line options to the compiler or via #define.
The preprocessor works without knowing anything about the types, even the builtin one.
BTW, you can still do the check using a static_assert like feature (boost has one for instance, C++0X will have one).
Edit: C99 and C++0X have also WCHAR_MIN and WCHAR_MAX macros in <stdint.h>
I think things like BOOST_STATIC_ASSERT could help.
Wouldn't you get basically what you want (compile error w/o the fancy message) by using a C_ASSERT?
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
sizeof() is a runtime compile-time function. You cannot call that in a preprocessor directive. I don't think you can check the size of wchar_t during preprocessing. (see Edit 2)
Edit: As pointed out in comments, sizeof() is mostly calculated at compile time. In C99, it can be used at runtime for arrays.
Edit 2: You can do asserts at build time using the techniques described in this thread.
char _assert_wchar_t_is_16bit[ sizeof(wchar_t) == 2 ? 1 : -1];
I've developed some macros that will effectively allow you to use sizeof within a macro condition. They're in a header file that I've uploaded here (MIT license).
It will permit for code like this:
#include <iostream>
#include "SIZEOF_definitions.h"
//You can also use SIZEOF_UINT in place of SIZEOF(unsigned, int)
// and UINT_BIT in place of SIZEOF_BIT(unsigned, int)
#if SIZEOF(unsigned, int) == 4
int func() { return SIZEOF_BIT(unsigned, int); }
#elif SIZEOF(unsigned, int) == 8
int func() { return 2 * SIZEOF_BIT(unsigned, int); }
#endif
int main(int argc, char** argv) {
std::cout SIZEOF(unsigned, long, int) << " chars, #bits = " << SIZEOF_BIT(unsigned, long, int) << '\n'
<< SIZEOF(unsigned, int) << " chars, #bits = " << SIZEOF_BIT(unsigned, int) << '\n'
<< SIZEOF(int) << " chars, #bits = " << SIZEOF_BIT(int) << '\n';
std::cout << func() << std::endl;
return 0;
}
Note the commas within SIZEOF(unsigned, long, int).