I'm trying to make sure I understand what the hidden assumptions here are.
This code here gives correct results.
#include <stdio.h>
#include <stdlib.h>
struct branch
{
char flag; //value
struct branch *l; //left child
struct branch *r; //right child
};
struct branch c={'c',NULL,NULL};
struct branch e={'e',NULL,NULL};
struct branch f={'f',NULL,NULL};
struct branch b={'b',&c,NULL};
struct branch d={'d',&e,&f};
struct branch a={'a',&b,&d};
void preorder(struct branch* t)
{
printf(&t->flag); //Seems ugly and errorprone
if(t->l) preorder(t->l);
if(t->r) preorder(t->r);
}
int main()
{
preorder(&a);
}
Output, as expected, is abcdef
Can someone confirm my suspicions, that this only works because two things:
char) up to the n-byte boundary are zeroed.I see no other explanation for printf working correctly otherwise, as it expects a zero-terminated char[].
Furthermore, is it wise to do things like that (outside of a single-target embedded code situation, where the optimisation may outweigh the readability and portability issues), ie. are these assumptions more-or-less universally true?
First week of intermittently messing with C, so I'm pretty green.
To verify your assumptions, you can inspect the code at runtime with a debugger or by using some printf.
For example, with:
char *ptr=(char *)&t;
printf("%02X %02X %02X %02X\n",ptr[0],ptr[1],ptr[2],ptr[3]);
Indeed the assumptions you identified are very often true, but you can't rely on them. I definitely would say that
printf(&t->flag);
is plainly wrong because it relies on assumptions that are not guaranteed by the standard.tt
You can prove 1 and 2 by yourself (i use x64, that's why all is 8bytes aligned in structures)
objdump ./main -s -j .data
Contents of section .data:
601030 00000000 00000000 00000000 00000000 ................
601040 63000000 00000000 00000000 00000000 c...............
601050 00000000 00000000 00000000 00000000 ................
601060 65000000 00000000 00000000 00000000 e...............
601070 00000000 00000000 00000000 00000000 ................
601080 66000000 00000000 00000000 00000000 f...............
601090 00000000 00000000 00000000 00000000 ................
6010a0 62000000 00000000 40106000 00000000 b.......@.`.....
6010b0 00000000 00000000 00000000 00000000 ................
6010c0 64000000 00000000 60106000 00000000 d.......`.`.....
6010d0 80106000 00000000 00000000 00000000 ..`.............
6010e0 61000000 00000000 a0106000 00000000 a.........`.....
6010f0 c0106000 00000000 ..`.....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With