1

So basically I want to be able to do something along these lines

char *test1 = "hey";
int test2 = (int)test1;
char *test3 = (char*) &test2;
printf("%s", test3);
// have the output as hey

Is this even possible? I know this isn't working correctly but I just want to know if there's a working method. Yes I want to use char pointers and ints, so no, I don't want to use strings

  • 1
    [C++: Is it safe to cast pointer to int and later back to pointer again?](http://stackoverflow.com/questions/3567905/c-is-it-safe-to-cast-pointer-to-int-and-later-back-to-pointer-again) – 001 Apr 13 '16 at 13:07
  • 1
    Note that `char *test1 = "hey";` should not compile. Some compilers have an extension that allows this but you should use `char test1[] = "hey";` or `const char* test1 = "hey";` or better yet `std::string test = "hey";` – NathanOliver Apr 13 '16 at 13:07
  • 1
    Is **what** even possible? You've written some code that does some iffy casts that may or may not do something sensible. What is it that you're trying to accomplish? – Pete Becker Apr 13 '16 at 13:31
  • Out of interest, why do you want to do this? – Sean Apr 13 '16 at 13:32
  • @JohnnyMopp - while that's an important point, it's not really what's going on here. There's another level of indirection, initializing `test3` with `(char*)&test2`. Note the `&` -- it's taking the **address** of `test2`. – Pete Becker Apr 13 '16 at 13:32

2 Answers2

2
char *test1 = "hey";
int test2 = (int)test1;
char *test3 = (char*) test2; // Note that the ampersand has been removed
printf("%s", test3);

might work if ints and pointers are the same size (they often are, but it's not guaranteed).

But when you assign test3, you are taking the address of test2, instead of its value, which is what I think you really meant to do.

Logicrat
  • 4,438
  • 16
  • 22
  • Pointers are usually _unsigned_ integers. – Ahmet Ipkin Apr 13 '16 at 13:07
  • Please check the answer as "accepted" if you want to give the deserved reputation to the user ;) – Ahmet Ipkin Apr 13 '16 at 13:10
  • 1
    @AhmetIpkin this answer exhibits undefined behaviour and should not be accepted. casting a pointer to an int is undefined behaviour. casting a string literal to a pointer to mutable char is undefined behaviour. casting a string literal (indirectly) to a pointer to mutable char is also undefined behaviour. – Richard Hodges Apr 13 '16 at 13:21
  • @RichardHodges Casting a `char *` to an `int` is NOT an undefined behaviour (`std::intptr_t` is optional and most of the time is `uint_t`) , you are simply reading the address of the literal (modifying that address is UB). Castings are pretty well defined operations on C / C++. Casting a string literal to a char pointer is also NOT an UB, it is an ERROR in any sane compiler - which can be fixed with assigning to a `const char*`. – Ahmet Ipkin Apr 13 '16 at 13:32
  • @AhmetIpkin this question is tagged c++. – Richard Hodges Apr 13 '16 at 13:33
  • @RichardHodges castings are still valid operations in C++. – Ahmet Ipkin Apr 13 '16 at 13:34
  • @AhmetIpkin §5.2.10 (para 4) "A pointer can be explicitly converted to any integral type large enough to hold it. The mapping function is implementation-defined." so to be exact, this operation is only well defined if an integer is at least as large as a pointer. This is often not the case. On all other matters, I stand by my reasoning. casting a string literal to a pointer to mutable chars is undefined behaviour. Therefore the entire program will exhibit undefined behaviour. – Richard Hodges Apr 13 '16 at 13:38
  • I am quite interested to see an architecture that a pointer is not the size of an unsigned integer. Besides, casting is never UB, _using_ that pointer might or might not, depending on usage. – Ahmet Ipkin Apr 13 '16 at 13:43
  • The question was "Is this even possible". In my answer, I attempted to make the minimal change to allow the original code to run. And I did note the caveat that it requires that `int` and a pointer be the same size. – Logicrat Apr 13 '16 at 14:05
  • @AhmetIpkin In the 1980s, I used several compilers, mostly for MacOS, that had 16-bit `int`s and 32-bit pointers. IIRC, the old "Lightspeed C" was that way. – Logicrat Apr 13 '16 at 14:09
1

The code represents undefined behaviour and is therefore incorrect.

There is, however a way to do what you want legally. See comments inline for explanations:

#include <cstddef>
#include <cstdint>
#include <cstdio>

int main()
{
    // string literals are const
    const char *test1 = "hey";

    // intptr_t is the only int guaranteed to be able to hold a pointer
    std::intptr_t test2 = std::intptr_t(test1);

    // it must be cast back to exactly what it was
    const char *test3 = reinterpret_cast<const char*>(test2);

    // only then will the programs behaviour be well defined
    printf("%s", test3);
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142