9 Replies - 990 Views - Last Post: 07 April 2017 - 04:40 AM

#1 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 5831
  • View blog
  • Posts: 19,880
  • Joined: 05-May 12

Undefined behavior: &(((st *)0)->m)

Posted 02 April 2017 - 01:39 PM

I learned C programming back in the 80's when this was the standard implementation of the offsetof() macro:
#define offsetof(st, m) ((size_t)&(((st *)0)->m))



My C programming teacher took time to explain why this macro works, and how valuable the offsetof() macro could be for cases when you had code than just varied by what member in a struct was being looked at, but was otherwise essentially duplicates of each other. Later, in my professional career, we often used pointer math tricks either using the concepts as in that offsetof() macro where a null pointer was involved.

Imagine my shock when I ran across the following post this morning:
Null Pointer Dereferencing Causes Undefined behavior

Also Wikipedia offsetof():

Quote

While this implementation works correctly in many compilers, it has undefined behavior according to the C standard,2 since it involves a dereference of a null pointer (although, one might argue that no dereferencing takes place, because the whole expression is calculated at compile time).


Apparently, I'd just been getting lucky that I happened to be using compilers that supported this undefined behavior.

2: Does &((struct name *)NULL -> B) cause undefined behaviour in C11?

Just feeling kind of lost today after having one of the foundational things I've learned has been destroyed.

Is This A Good Question/Topic? 1
  • +

Replies To: Undefined behavior: &(((st *)0)->m)

#2 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1265
  • View blog
  • Posts: 4,979
  • Joined: 09-June 09

Re: Undefined behavior: &(((st *)0)->m)

Posted 03 April 2017 - 02:38 PM

Looks like the odds were in your favor since most of them will evaluate the offsetof at compile time which won't technically dereference the NULL pointer.

Very interesting, I actually have never heard of that macro. Learn something new everyday.
Was This Post Helpful? 0
  • +
  • -

#3 Xupicor  Icon User is offline

  • Nasal Demon
  • member icon

Reputation: 456
  • View blog
  • Posts: 1,179
  • Joined: 31-May 11

Re: Undefined behavior: &(((st *)0)->m)

Posted 04 April 2017 - 07:57 AM

Interesting. ((st *)0)->m does look like a sure UB at a glance, even more so if you form it as ( *((st *)0) ).m.

I'll have to read through the links and arguments for why it's "not" at some point, even though it is. ; )
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 5831
  • View blog
  • Posts: 19,880
  • Joined: 05-May 12

Re: Undefined behavior: &(((st *)0)->m)

Posted 04 April 2017 - 08:49 AM

The address of operator is what makes the difference... At least that was the reasoning as explained to me by my teacher. Without the address of operator, yes, definitely undefined behavior.
Was This Post Helpful? 0
  • +
  • -

#5 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon


Reputation: 6966
  • View blog
  • Posts: 14,572
  • Joined: 16-October 07

Re: Undefined behavior: &(((st *)0)->m)

Posted 04 April 2017 - 11:55 AM

When I first started programming, graphics were kind of primitive; particularly on x86 machines. Common practice was "direct screen writes" where you literally threw bytes in the display buffer to be mirrored to the screen on next refresh.

I recall in Pascal we'd regularly write characters to the screen with code like mem[$B800:(2*x)+(y*$A0)]:=ord(chr);.

The hacky code where we directly touched unsecured memory locations is a relic of a bygone age. Probably for the best.

Terminate Stay Resident programs were great fun to write. They were essentially viruses, but just before the days when wild virii were a threat. It was like computer free love then. Things are much safer now.
Was This Post Helpful? 0
  • +
  • -

#6 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 5831
  • View blog
  • Posts: 19,880
  • Joined: 05-May 12

Re: Undefined behavior: &(((st *)0)->m)

Posted 05 April 2017 - 06:13 AM

Yes. I remember those direct screen writes and TSR days! ModeX anyone? :)

I'll post later with details of why I started down the path of looking at offsetof() if I find any gaps in my day today or tomorrow. The short version is that I was looking at object oriented approaches to tackle the question here without two dimensional arrays and not having to use a std::map or duplicated code to access each of the subjects.
Was This Post Helpful? 0
  • +
  • -

#7 Salem_c  Icon User is offline

  • void main'ers are DOOMED
  • member icon

Reputation: 2129
  • View blog
  • Posts: 4,196
  • Joined: 30-May 10

Re: Undefined behavior: &(((st *)0)->m)

Posted 05 April 2017 - 09:00 AM

Why worry about how it's declared (or how hacky code declared it in the past)?

c99-standard said:

7.17 Common definitions <stddef.h>

offsetof(type, member-designator)
which expands to an integer constant expression that has type size_t, the value of
which is the offset in bytes, to the structure member (designated by member-designator),
from the beginning of its structure (designated by type).


You no longer have to guess how to declare offsetof(), whether the apparent NULL dereference is UB or not, or indeed whether the particular implementation of offsetof() even uses a NULL to begin with.
Was This Post Helpful? 0
  • +
  • -

#8 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 5831
  • View blog
  • Posts: 19,880
  • Joined: 05-May 12

Re: Undefined behavior: &(((st *)0)->m)

Posted 06 April 2017 - 05:41 AM

My worry is for any of my old code where I did not use the offsetof() macro to do similar type of offset calculations. Basically, since I knew how the macro worked and trusted it how it worked, I essentially rolled my own to do computations of deltas between structure members.
Was This Post Helpful? 0
  • +
  • -

#9 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1851
  • View blog
  • Posts: 6,647
  • Joined: 19-February 09

Re: Undefined behavior: &(((st *)0)->m)

Posted 06 April 2017 - 08:09 PM

Appearing soon in...Nightmare.In.Code.
Was This Post Helpful? 0
  • +
  • -

#10 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 5831
  • View blog
  • Posts: 19,880
  • Joined: 05-May 12

Re: Undefined behavior: &(((st *)0)->m)

Posted 07 April 2017 - 04:40 AM

Surprisingly, the macros made the code very readable. It's the implementation behind them that will need to be updated to use offsetof() instead of its own casting and address of's.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1