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