0

I got a Question in a mock test which is not running in IDE but I could not understand the concept behind that piece of code given in test.

printf (“%c, %c”, *( (char*) q + 1) , *( (char*) q + 2) ) ; Here how an pointer to struct q can access the members of pointers using numbers.

Here is the link for the code

https://ide.geeksforgeeks.org/7V6mVJZvre

  • Bad idea. This is undefined behavior. – Eugene Sh. Apr 20 '21 at 18:08
  • Post your code in the question, not only via a link. – Jabberwocky Apr 20 '21 at 18:09
  • What's undefined about it, @EugeneSh.? – John Bollinger Apr 20 '21 at 18:18
  • @JohnBollinger What if it hits a padding byte? – Eugene Sh. Apr 20 '21 at 18:18
  • @EugeneSh. it is allowed to read that byte even if it is padding. – John Bollinger Apr 20 '21 at 18:19
  • @JohnBollinger But what about printing it? – Eugene Sh. Apr 20 '21 at 18:19
  • What about it? You may not be able to predict the output, but that does not make the behavior undefined. – John Bollinger Apr 20 '21 at 18:21
  • @JohnBollinger There were some discussions few times regarding library functions being passed arguments with indeterminate values (specifically `printf`) and some credible members claimed it is UB (for example [here](https://stackoverflow.com/questions/59415696/why-on-entering-a-wrong-type-of-value-as-input-the-variable-b-is-always-assi#comment105022880_59415696)). Not that you are not credible. But I can't find any standard reference, only about indeterminate values of objects with automatic storage class (In Annex J2) – Eugene Sh. Apr 20 '21 at 18:36
  • @EugeneSh., Annex J is not normative, so you need to try to find the basis for its claims of undefined behavior elsewhere in the standard. The main issue with indeterminate values in general is that they may be trap representations, but type `char` does not afford any trap representations, so the values read by the OP's code are at worst "unspecified" ordinary `char` values. The same applies to structure objects, for that matter, albeit not necessarily to their members. – John Bollinger Apr 20 '21 at 18:53

2 Answers2

1

If q is a pointer to any object type, then casting it to a character type provides a means to access the bytes of the representation of the pointed-to object, if any. However, if q is a pointer to a structure type then the code you present does not access the members per se. Although the representation of an instance of the structure type comprises representations of all the structure members, (char*) q + 1 is not selecting a member, but rather a byte (in the form of a pointer to that byte) -- the one at offset 1 from the beginning of the structure. That byte could be part of the first member (which starts at offset 0), part of the second member, or not part of any member.

Given (char*) q + 1 being a pointer to the byte at offset 1 from the start of object *q, and *q being at least two bytes in size, the expression *( (char*) q + 1) evaluates to the value of that byte. It is equivalent to ((char *)q)[1].

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
0

In c, struct members just memory space mapped to that struct definition. A struct with three chars means 3 byte space mapped to the this struct.

q is a pointer. So q + 1 means one address forward to the base struct address

(char*) means this is not a struct anymore this is a char pointer

*( (char*) q + 2) ) or simply *x means dereference the pointer so get the char value.

There are some exceptions (if not all members are the same type) check Structure padding and packing

Furkan
  • 352
  • 3
  • 12