Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does (int*) &var mean?

Tags:

c

pointers

What is the meaning of (int*) &i?

  char i;
  int* p = (int*) &i;
  ...
  *p = 1234567892;
  ...

If it was * &i, I would understand. But in this case, this an "int" in there.

like image 637
Stoatman Avatar asked Feb 15 '15 03:02

Stoatman


People also ask

What does int *) p do in C?

What does int *) p do in C? Pointers and Addresses A pointer is a variable that contains the address of a variable. Pointers are defined according to the type they point to. The declaration is supposed to be a mnemonic: int *p; says that p points to a variable of type int. The * is actually an operator.

Is int * and int * Same?

int * means a pointer to an integer in your memory. The [] bracket stands for an array. int a[10]; would make an array of 10 integers. int *a; would make a pointer to an integer.

What does * After int mean in C++?

It's the type of a pointer to a pointer to an int . If you dereference a variable t of this type (like this: *t ), you get a pointer to an int . If you dereference it twice (like this: **t ), you get an int . Follow this answer to receive notifications.

What is meant by int * p?

int *p = &x; ● This means "p is a pointer to int. Its value is the. address where x is stored"


2 Answers

&i : means to take the address of i (which is a char*)

(int*)&i : casts that pointer to be a pointer to integer (which is bad/wrong to do, but you told the compiler to do it so it won't even give a warning)

int* p = (int*)&i; : a statement that says to store the pointer of i in p (and cast it too: the compiler won't even complain)

*p = 1234567892; : write this value, which is several bytes to the base location pointed to by p (which although p thinks it points to an int, is to char!). One of those bytes will end up in i, but the others will over write the bytes neighboring i.

like image 125
Michael Avatar answered Nov 15 '22 06:11

Michael


The construct (int *) &var, where var is a char, takes a pointer to var, and then converts it to a pointer of a different type (namely int). The program later writes an int value into the pointer. Since the pointer actually points to a char, an int value does not fit, which triggers undefined behavior, which is a fancy name for "literally anything (that your computer can physically accomplish) could happen -- this program is buggy".

EDIT: As requested, some standardology to explain why this program has undefined behavior. All section references below are to N1570, which is the closest approximation to the official text of C2011 that can be accessed online for free.

As a preamble, when reading the text of the C standard, you need to know that the word "shall" has special significance. Any sentence containing the word "shall" imposes a hard requirement on either the program, or the compiler and runtime environment; you have to figure out which from context. There are two kinds of hard requirements on the program. If a "shall" sentence appears in a "constraints" section, then the compiler is required to diagnose violations (§5.1.1.3) (the standard never flat out says that a program must be rejected, but that's the usual line drawn between hard errors and warnings). If a "shall" sentence appears somewhere else, then the compiler isn't required to diagnose it, but a program that violates the requirement has undefined behavior (§4p1,2). Sometimes the text says "If X, then the behavior is undefined" instead; there's no difference in the consequences.

First off, the conversion (int *) &var converts char * to int *, which is explicitly allowed by §6.3.2.3p7 if and only if the value of the pointer-to-char is properly aligned for an object of type int.

A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer.

There's nothing in the code shown that would ensure that var is aligned appropriately for an int, so the program might already have triggered undefined behavior at this point, but let's assume it is aligned correctly. Saving a value of type int * into a variable declared with that type is unproblematic. The next operation is *p = integer_literal. This is a write access to the stored value of the object var, which must obey the rules in §6.5p6,7:

  1. The effective type of an object for an access to its stored value is the declared type of the object, if any. [... more text about what happens if the object has no declared type; not relevant here ...]

  2. An object shall have its stored value accessed only by an lvalue expression that has one of the following types:

    • a type compatible with the effective type of the object,
    • a qualified version of a type compatible with the effective type of the object,
    • a type that is the signed or unsigned type corresponding to the effective type of the object,
    • a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
    • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
    • a character type

For simple arithmetic types like int and char, compatible type means the same type after stripping typedefs. (The exact definition is spread over §§ 6.2.7, 6.7.2, 6.7.3, and 6.7.6.) What matters for this analysis is simply that the declared type of var is char, but the lvalue expression *p has type int; int is not compatible with char, and int is not a character type. Therefore this program violates a requirement stated with the word "shall", which is not within a section named "constraints", and its behavior is undefined.

Note the asymmetry of the last bullet point. Any object may have its stored value accessed by an lvalue expression with character type, but an object declared to have character type may not be accessed by an lvalue expression with an incompatible type. Yes, that means the common idiom of accessing a large array of characters (such as a buffer of data read from a file) "four at a time" via a pointer to int is, strictly speaking, invalid. Many compilers make a special exception to their pointer-aliasing rules for that case, to avoid invalidating that idiom.

However, accessing a single char via a pointer to int is also invalid because (on most systems) int is bigger than char, so you read or write bytes beyond the end of the object. The standard doesn't bother distinguishing that case from the array case, but it will blow up on you regardless.

like image 24
zwol Avatar answered Nov 15 '22 05:11

zwol