10

In last two statements, any real difference between the realPointer and fakePointer. Will they both provide the same functionality?

  int num = 0;

  int *realPointer = #
  int fakePointer = #
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Yet A-beyene
  • 383
  • 1
  • 2
  • 8
  • 34
    When asking "do these two bits of C code provide the same functionality", please post code that actually compiles. One of the above variables does something, the other is a compile-time error: clearly, a compile time error does not have the same functionality as something that compiles. – Yakk - Adam Nevraumont Mar 11 '16 at 14:44
  • @Yakk With `gcc` (for example), this is only a warning, not an error: `warning: initialization makes integer from pointer without a cast` – Tavian Barnes Mar 11 '16 at 22:18

5 Answers5

24
int fakePointer = #

This is not valid C, it breaks the rules of simple assignment and will not compile.

However, had you done int fakePointer = (int)# then the only difference would be that there are no guarantees that you can use fakePointer reliably, conversions from pointers to integers are implementation-defined and could potentially also lead to undefined behavior (6.3.2.3):

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.

To safely and portably convert between pointers and integers, you should not use int but the type uintptr_t found in stdint.h.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • For the benefit of the OP one might add that pointer sizes are often 64 bit on, well, 64 bit architectures (modern PC processors with a 64 bit OS) while **`int` sizes even on a 64 bit architecture are often 32 bit** (gcc 4.9.3 on x86_64 Cygwin/Windows 7/core i7, and Visual Studio 2013 targeting x64, same PC). On such systems the pointer -> int -> pointer conversion should result in invalid addresses lacking the higher 32 bits. – Peter - Reinstate Monica Mar 11 '16 at 13:55
  • 2
    @PeterA.Schneider More importantly, `int` is a signed type, but there exist no negative addresses. So if `int` is 32 bit and your pointer type is 32 bit, it won't work either, you'd invoke undefined behavior when converting pointers that have the msb set. – Lundin Mar 11 '16 at 13:59
  • @Lundin: I don't think the C standard cares whether negative addresses exist or not. In a sense, current x86-64 systems use both positive and negative virtual addresses, usually split at the user/kernel boundary. – Ian Abbott Mar 11 '16 at 15:56
  • @IanAbbott: That's not the problem. The problem is C does not guarantee that all bit patterns are valid integers, so you could produce a trap representation. – Kevin Mar 11 '16 at 16:04
  • @Kevin: The problem is not that addresses may or may not be negative. The problem is that converting a pointer value to an integer type that cannot represent the value results in undefined behavior. (But we're just arguing over niggly semantics here!) – Ian Abbott Mar 11 '16 at 18:28
6

A variable declared as a pointer is semantically different from a variable not declared as a pointer. The compiler (and the language) will allow you do do things with a pointer you can not do with a non-pointer. And the opposite of course.

The biggest different is that you can dereference a pointer, but you can't do that to a non-pointer.

For example, using the variables in your code, then we can do *realPointer = 5 to make num be assigned the value 5, but doing *fakePointer = 5 is not allowed and doesn't make sense since fakePointer isn't actually a pointer.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
4
int num = 0;
int *realPointer = #
int fakePointer = #

In last two statements, any real difference between the realPointer and fakePointer.

Your fakePointer is NOT a pointer. It's an integer with the value as the address of variable num. You may get away when compiling this with default options. But as Lundin pointed out, this is indeed an invalid code. Using gcc with CFLAGS="-g -Wall -std=c99 -O3 -pedantic-errors" flag, you'd get this error:

 error: initialization makes integer from pointer without a cast

While your realPointer really does point to variable num, and you can dereference it. You can do nothing like that with your fakePointer - and in fact the assignment to fakePointer itself is invalid.

artm
  • 17,291
  • 6
  • 38
  • 54
1

If you go for the literal values (i.e. actual values) held by these two variables, they are same(i.e. address of variable num) but only values are same. But as told by others they are semantically two different variables and cannot be used interchangeably.

Coming to your last question:

Will they both provide the same functionality?

Answer: No, they do not.

Reasoning they are not of the same type.

Your first question:

any real difference between the realPointer and fakePointer.

There are so many differences, and the most basic differences are:
  1. realPointer holds the address of num and is a pointer so if you change the value of num ( by changing using num variable or *realPointer) it is reflected at both the places, but it is not the case with the fakePointer
  2. you can pass realPointer to functions and any changes made in side the function calls will be reflected back to the callee function.
1

Besides the fact that this

 int fakePointer = #

may lead to one or more of the following

  • undefined behaviour by breaking the C language's "rules" (which in turn might lead to "anything happens")
  • losing significant digits during conversion
  • fail to compile at all

The following differences apply:

  • The *-/dereferencing-operator cannot by applied to the int typed fakePointer.
  • Doing fakePointer++ would most likely result in something different then doing realPointer++. This applies to all other ways of adding and subtracting any value (but 0). Read on "pointer arithmetic" vs. "arithmetic" for details.
  • It is not possible to apply the []-/indexing-operator to the int typed fakePointer.
Community
  • 1
  • 1
alk
  • 69,737
  • 10
  • 105
  • 255