I was looking through stdlib.h within the include files for Dev-Cpp and I found a certain line:
#define _PTR_LD(x) ((unsigned char *)(&(x)->ld))
I then tried to use _PTR_LD in a program as follows:
class Thing {
public:
Thing();
int ld;
};
int main() {
Thing x;
x.ld = 8;
cout << _PTR_LD(x) << endl;
system("pause");
return 0;
}
I thought it would return the value for the attribute ld within x, but I got the following error message:
15 10 C:\Users\John\Desktop\Untitled1.cpp [Error] base operand of '->' has non-pointer type 'Thing'
I tried to search for _PTR_LD() but I found nothing about it. Does anyone know anything about _PTR_LD()?
What it does literally is take an expression that evaluates to a pointer, x, and returns a pointer to x->ld, reinterpreted as an unsigned char*.
What you're doing doesn't compile because -> has higher precedence than &, so your code evaluates to &(x->ld), which is invalid. If you instead printed the following:
x.ld = 'a';
std::cout << ( _PTR_LD(&x)) << std::endl;
then you'd see a printed, since you're reinterpreting &(x.ld) as a C-string, and that memory happens to look like the string {'a', 0}.
As to why this macro exists, I don't know. Does it matter? It's a reserved, internal-use macro.
Related
Suppose I have this code:
#include <iostream>
struct Mine
{
int a;
int b;
};
int main()
{
int Mine::* memberPointerA = &Mine::a;
int Mine::* memberPointerB = &Mine::b;
std::cout << memberPointerA;
std::cout << "\n";
std::cout << memberPointerB;
}
When I run this with Microsoft Visual C++ (2015)
I get the following output
1
1
The output I expect is something more like this:
1
2
So this begs the question: Is this printing of a member pointer defined behavior?
There's a defined conversion from pointer to bool. Since the member variable pointers are not NULL, they evaluate as true and print as 1.
The key issue at hand is that a pointer-to-member cannot be converted to void*, which is what the overload that usually handles printing pointers takes.
Thus, the next best conversion is used, which is the conversion pointer->bool. Both pointers are not null pointers, thus you get the output you see.
If you try printing "normal" pointers (as opposed to pointers to member), you would get the some output along the lines of what you expected initially.
I have read this post and the answers indicate a behavior described in a paragraph below. I am not trying to make it work on my machine, or find a workaround to make it work on my machine, it is a question of is it defined behavior according to the standard.
Consider the following code which creates an int variable, an int-reference variable, and prints out the result of calling the address-operator on the int-reference variable
#include <iostream>
int main() {
int a = 70;
int& b = a;
std::cout << &b << std::endl;
return 0;
}
It prints out what I would expect, which is an address in memory, i.e., the address of int variable a.
But now I change int to char, or unsigned char, or signed char, and both on Xcode (Version 6.4) and Visual Studio (VS 2013 Ultimate) I get unexpected behavior.
#include <iostream>
int main() {
// or unsigned char or signed char, same weird behavior
char a = 70;
char& b = a;
std::cout << &b << std::endl;
return 0;
}
In Xcode, the console prints something like F\330\367\277_\377 . I get that F is the ASCII code for 70, but I do not understand the rest of it. I assume it is also a set of ASCII characters, since on Visual Studio it prints out the F followed by some weird characters.
I tried other integer types and it worked fine. And I know that often char/signed char/unsigned char or some combination of them are implemented as the same type. The only thing I can think of is that the reference type is being implemented as a pointer type and then interpreting the call to &b as returning a pointer type, and then std::cout is taking its input to mean to print out all characters in a char array.
Is this defined behavior?
To reiterate: my question is more specifically, is this a defined behavior which is part of the standard, is this behavior not defined by the standard, is this a non-standard implementation of the compilers? Something else?
I suppose the behaviour of the following snippet is supposed to be undefined but I just wanted to make sure I am understanding things right.
Let's say we have this code:
#include <iostream>
int main()
{
std::cout << "mamut" - 8 << std::endl;
return 0;
}
So what I think this does is (char*)((int)(const char*) - (int)), though the output after this is pretty strange, not that I expect it to make any real sense. So my question is about the casting between char* and int - is it undefined, or is there some logic behind it?
EDIT:
Let me just add this:
#include <iostream>
int main ()
{
const char* a = "mamut";
int b = int(a);
std::cout << b << std::endl;
std::cout << &a <<std::endl;
// seems b!= &a
for( int i = 0; i<100;i++)
{
std::cout<<(const char*)((int)a - i)<<std::endl;
}
return 0;
}
The output after i gets big enough gives me a something like _Jv_RegisterClasses etc.
Just for the record:
std::cout << a - i << std::endl;
produces the same result as:
std::cout<<(const char*)((int)a - i)<<std::endl;
There is no cast, you are merely telling cout that you want to print the string at the address of the string literal "mamut" minus 8 bytes. You are doing pointer arithmetic. cout will then print whatever happens to be at that address, or possibly crash & burn, since accessing arrays out of bounds leads to undefined behavior.
EDIT
Regarding the edit by the op: converting an address to int doesn't necessarily result in a correct number identical to the address. An address doesn't necessarily fit in an int and on top of that, int is a signed type and it doesn't make any sense to store addresses in signed types.
To guarantee a conversion from pointer to integer without losses, you need to use uintptr_t from stdint.h.
To quote the C standard 6.3.2.3 (I believe C++ is identical in this case):
Any pointer type may be converted to an integer type. Except as
previously specified, the result is implementation-defined. If the
result cannot be represented in the integer type, the behavior is
undefined. The result need not be in the range of values of any
integer type.
There is no casting going on. "mamut" is a pointer to characters, and - 8 will do pointer arithmetic on it. You are right that it's undefined behavior, so even though the semantic behavior is pointer arithmetic, the runtime behavior can be literally anything.
You are printing string starting from address of "mamut" minus 8 bytes till null terminator i.e. in total 8+5 = 13 chars
I cannot find information about a behavior of sizeof (at least in gcc 4.6+). The following code works and produces the "expected" result (4, 1, 8), but I'm wondering why. I checked several questions but none show an example like this one.
#include<iostream>
int f1(int) {
return 0;
}
char f2(char) {
return 0;
}
double f3() {
return 0;
}
int main() {
std::cout << sizeof(f1(0)) << std::endl;
std::cout << sizeof(f2('0')) << std::endl;
std::cout << sizeof(f3()) << std::endl;
return 0;
}
An answer would be much appreciated.
Thanks.
The sizeof operator can take a type or an expression as an argument and returns the size of its argument. You're using expressions, so it returns the size of those expressions. The expression is not evaluated at run-time — so the functions are never invoked. But the correct (overloaded) function is used to determine the size of the result.
In a (now-deleted) comment, user1919074 said:
sizeof(f1) would not work
Brain fart
In C, sizeof(f1) would work since it would return the size of a pointer to function.
The sizeof() operator can't be applied direct to a function name. It has special rules, and when applied to an array, the normal 'decay' to a pointer doesn't occur. Similarly, the change of a function name to a function pointer doesn't occur with sizeof(). (Of course, you have to poke GCC hard with -pedantic to get it to give the warning/error; otherwise, it returns 1 as the size of the function.)
What is happening in the functions
int f1(int) {
return int(0);
}
char f1(char) {
return char(0);
}
double f1() {
return double(0);
}
What is happening later.
std::cout << sizeof(int(0)) << std::endl;
std::cout << sizeof(char('0')) << std::endl;
std::cout << sizeof(double(0)) << std::endl;
Because you are printing the sizeof the value of what is returned from the function
ISO/IEC 14882 on C++ says (section 5.3.3 - page 79):
says
"The size operator shall not be applied to an expression that has
function or incomplete type,..."
Also notice the compilation warning with the -pedantic option enabled...
warning: invalid application of 'sizeof' to a function type
f1 returns an integer which takes 4 bytes.
f2 returns a character which takes 1 byte.
f3 returns a double which takes 8 bytes.
So all sizeof() does is return the size of its argument.
#include <iostream>
using namespace std;
typedef int MYINT;
int main()
{
int y = MYINT(); // As expected, y = 0; value initialization
cout << MYINT(); // Error
cout << sizeof(MYINT()); // Error
}
Why the last two lines in the main function before the closing brace give error? Why is the expression MYINT() treated differently in different contexts? Any Standard reference will be helpful.
MYINT() can, depending on context, be interpreted as an expression of type MYINT, or a specifier of a function type taking no arguments and returning MYINT.
In some situations, where either an expression or a type specifier is valid, this gives an ambiguity; this is resolved by interpreting it as a type specifier if possible (EDIT: C++03 8.2/2, if you want a Standard reference).
sizeof can take either an expression, or a parenthesised type specifier, as it's argument, giving this ambiguity. So here MYINT() is interpreted as a type specifier; then you get an error, since sizeof can't be applied to a function type.
EDIT: You can fix the error by removing the parentheses so it will be interpreted as an expression (sizeof MYINT()), adding extra parentheses so it isn't a valid type specifier (sizeof((MYINT()))), or changing it to the correct type (sizeof(MYINT)).
cout << MYINT() is unambiguous, so there should be no error, and indeed there isn't on my compiler. What is the error, and what is your compiler?
If your MINTINT is typedef int MYINT then MYINT() is not a function but is int() which is a default initialization, equivallent to int y = 0 or int y = int(0).
Your second line, ie cout << MYINT() compiles correctly for me with g++ -Wall -ansi -pedantic for the same reason.
But g++ will complain for the sizeof with the following error error: invalid application of "sizeof" to a function type because it interprets MYINT() as "a call to a default constructor for int" (EDIT: this is not correct) "a function type returning MYINT which is not allowed" (EDIT: this is the correct answer, see Mike's). But this a nothing to do with the typedef.
Summary:
#include <iostream>
typedef int myint;
int main()
{
int y = myint();
int z = myint(0);
std::cout << y << z; // Will output 0 0
std::cout << std::endl << myint(0) << myint(); // Will output 0 0
std::cout << sizeof(int()); // The error is here; same with sizeof(myint())
}
Edit (again)
As said in the comment is the cout lines doesn't work for you, this is because you probably forgot to include <iostream>.
Edit
Look also the answer of Mike Seymour for an explanation of the ambiguity with sizeof.
// OK. Implicit conversion to int.
int y = MYINT();
// OK. Implicit conversion again. Which compiler do you use?
cout << MYINT();
// Invalid. Tries to get size of a function that returns MYINT,
// because sizeof expects a type-id and according to 8.2/2,
// which is forbidden according to the C++ Standard 5.3.3/1
cout << sizeof(MYINT());
// Do you want this instead?
cout << sizeof(MYINT);
I do not see any error for the cout << MYINT(); line. However I see invalid application of 'sizeof' to a function type for the cout << sizeof(MYINT()); line. The problem is the () around MYINT(). The C++ standard says this about sizeof and how it is parsed:
sizeof unary-expression
sizeof ( type-id )
There is a parsing ambiguity between sizeof unary-expression and sizeof ( type-id ). It is resolved by using longer match. It parses sizeof (MYINT()) as sizeof ( type-id ), MYINT() is a function type and thus you see the error.
Why the last two lines in the main function before the closing brace give error?
cout << MYINT(); doesn't work because cout is not defined. Once you do #include <iostream> and using std::cout, it will work fine.
sizeof(MYINT()) does indeed not work, but sizeof(int()) doesn't work either, so that's to be expected. sizeof(MYINT) will work just fine.
Why is the expression MYINT() treated differently in different contexts?
It's not. In every case MYINT() behaves exactly like int().