0
votes

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;
3
It's undefined behavior but not because of the reasons you think. Google pointer arithmetic.Captain Obvlious
You seem to assume that const char* is converted to int when you subtract 8. The assumption is wrong.eerorika
Why is the assumption wrong? I mean you cannot add char*, as + is not defined for char* + char*.lightxbulb
Also your edit has nothing to do with the original question. Please just ask one question per post, make a new post if you have a different question.Lundin
The edit is pretty much the same program but with i getting bigger(basically you'll see other results apart from "mamut" - 8 ). I made the for cycle cause with each i it prints out the output I was talking about.lightxbulb

3 Answers

5
votes

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.

1
votes

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.

0
votes

You are printing string starting from address of "mamut" minus 8 bytes till null terminator i.e. in total 8+5 = 13 chars