Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

86%
+11 −0
Q&A Behavior of Pointer Arithmetic on the Stack

Generally speaking, pointer arithmetic is undefined behavior unless carried out on arrays. This is how the additive operators behave, C17 6.5.6: For the purposes of these operators, a pointer to...

posted 3y ago by Lundin‭  ·  edited 3y ago by Lundin‭

Answer
#3: Post edited by user avatar Lundin‭ · 2021-12-14T12:26:43Z (almost 3 years ago)
  • Generally speaking, pointer arithmetic is undefined behavior unless carried out on arrays. This is how the additive operators behave, C17 6.5.6:
  • > For the purposes of these operators, a pointer to an object that is not an element of an array behaves
  • the same as a pointer to the first element of an array of length one with the type of the object as its
  • element type.
  • > /--/
  • > If both the pointer operand and the result point
  • to elements of the same array object, or one past the last element of the array object, the evaluation
  • shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past
  • the last element of the array object, it shall not be used as the operand of a unary * operator that is
  • evaluated.
  • So your code has undefined behavior - during pointer arithmetic `b` is to be regarded as an array `int[1]` and you access it out of bounds.
  • Furthermore, the C standard doesn't know or mentioning anything about stacks and stack frames - there's no guarantees of the underlying memory layout at all. For example a compiler for a 64 bit CPU with 32 bit int might decide to insert padding between the two integers and that's perfectly fine as far as C goes - there's no guarantee about adjacent allocation unless you use structs or arrays.
  • Also, while down-counting stacks are most common, some CPUs like for example Microchip PIC have up-counting stacks. Other CPUs don't even have stacks! For example I've worked with writing C for a very low end MCU (Freescale RS08) which didn't have a stack. I was painful but perfectly possible. There are similar stackless, extremely low end 4 bit MCUs used in some consumer electronics.
  • Generally speaking, pointer arithmetic is undefined behavior unless carried out on arrays. This is how the additive operators behave, C17 6.5.6:
  • > For the purposes of these operators, a pointer to an object that is not an element of an array behaves
  • the same as a pointer to the first element of an array of length one with the type of the object as its
  • element type.
  • > /--/
  • > If both the pointer operand and the result point
  • to elements of the same array object, or one past the last element of the array object, the evaluation
  • shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past
  • the last element of the array object, it shall not be used as the operand of a unary * operator that is
  • evaluated.
  • So your code has undefined behavior - during pointer arithmetic `b` is to be regarded as an array `int[1]` and you access it out of bounds.
  • Furthermore, the C standard doesn't know or mention anything about stacks and stack frames - there's no guarantees from the standard of the underlying memory layout at all. For example a compiler for a 64 bit CPU with 32 bit `int` might decide to insert padding between the two integers and that's perfectly fine as far as C goes - there's no guarantee about adjacent allocation unless you use structs or arrays.
  • Also, while down-counting stacks are most common, some CPUs like for example Microchip PIC have up-counting stacks. Other CPUs don't even have stacks! For example I've worked with writing C for a very low end MCU (Freescale RS08) which didn't have a stack. I was painful but perfectly possible. There are similar stackless, extremely low-end 4 bit MCUs used in some consumer electronics.
#2: Post edited by user avatar Lundin‭ · 2021-12-14T08:35:51Z (almost 3 years ago)
  • Generally speaking, pointer arithmetic is undefined behavior unless carried out on arrays. This is how the additive operators behave, C17 6.5.6:
  • > For the purposes of these operators, a pointer to an object that is not an element of an array behaves
  • the same as a pointer to the first element of an array of length one with the type of the object as its
  • element type.
  • > /--/
  • > If both the pointer operand and the result point
  • to elements of the same array object, or one past the last element of the array object, the evaluation
  • shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past
  • the last element of the array object, it shall not be used as the operand of a unary * operator that is
  • evaluated.
  • So your code has undefined behavior - during pointer arithmetic `b` is to be regarded as an array `int[1]` and you access it out of bounds.
  • Furthermore, the C standard doesn't know or mentioning anything about stacks and stack frames - there's no guarantees of the underlying memory layout at all.
  • Also, while down-counting stacks are most common, some CPUs like for example Microchip PIC have up-counting stacks. Other CPUs don't even have stacks! For example I've worked with writing C for a very low end MCU (Freescale RS08) which didn't have a stack. I was painful but perfectly possible. There are similar stackless, extremely low end 4 bit MCUs used in some consumer electronics.
  • Generally speaking, pointer arithmetic is undefined behavior unless carried out on arrays. This is how the additive operators behave, C17 6.5.6:
  • > For the purposes of these operators, a pointer to an object that is not an element of an array behaves
  • the same as a pointer to the first element of an array of length one with the type of the object as its
  • element type.
  • > /--/
  • > If both the pointer operand and the result point
  • to elements of the same array object, or one past the last element of the array object, the evaluation
  • shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past
  • the last element of the array object, it shall not be used as the operand of a unary * operator that is
  • evaluated.
  • So your code has undefined behavior - during pointer arithmetic `b` is to be regarded as an array `int[1]` and you access it out of bounds.
  • Furthermore, the C standard doesn't know or mentioning anything about stacks and stack frames - there's no guarantees of the underlying memory layout at all. For example a compiler for a 64 bit CPU with 32 bit int might decide to insert padding between the two integers and that's perfectly fine as far as C goes - there's no guarantee about adjacent allocation unless you use structs or arrays.
  • Also, while down-counting stacks are most common, some CPUs like for example Microchip PIC have up-counting stacks. Other CPUs don't even have stacks! For example I've worked with writing C for a very low end MCU (Freescale RS08) which didn't have a stack. I was painful but perfectly possible. There are similar stackless, extremely low end 4 bit MCUs used in some consumer electronics.
#1: Initial revision by user avatar Lundin‭ · 2021-12-14T07:59:50Z (almost 3 years ago)
Generally speaking, pointer arithmetic is undefined behavior unless carried out on arrays. This is how the additive operators behave, C17 6.5.6:

> For the purposes of these operators, a pointer to an object that is not an element of an array behaves
the same as a pointer to the first element of an array of length one with the type of the object as its
element type.  
> /--/  
> If both the pointer operand and the result point
to elements of the same array object, or one past the last element of the array object, the evaluation
shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past
the last element of the array object, it shall not be used as the operand of a unary * operator that is
evaluated.

So your code has undefined behavior - during pointer arithmetic `b` is to be regarded as an array `int[1]` and you access it out of bounds.

Furthermore, the C standard doesn't know or mentioning anything about stacks and stack frames - there's no guarantees of the underlying memory layout at all. 

Also, while down-counting stacks are most common, some CPUs like for example Microchip PIC have up-counting stacks. Other CPUs don't even have stacks! For example I've worked with writing C for a very low end MCU (Freescale RS08) which didn't have a stack. I was painful but perfectly possible. There are similar stackless, extremely low end 4 bit MCUs used in some consumer electronics.