Herbert Kleebauer said:
My question was about the first example a. I know that there are
work arounds and I used one of them in my code. I did it the same
way as also Jens Toerring suggested in his reply:
const char sockaddr_un[]=
{1,0,'/','t','m','p','/','.','X','1','1','-','u','n','i','x','/','X','0'};
But there are two disadvantages, by splitting the short into two bytes
you explicitly have to specify the byte order and the string is much
more cumbersome to write (and harder to read) than a simple "/tmp/.X11-unix/X0".
An initialization like
char ab[ ] = "/tmp/.X11-unix/X0";
has a well-defined meaning in C but not the one you want. The
stuff in double quotes is a string literal that always ends
with a terminating '\0'. And allowing it to be used in the
initialization of a char array is actually syntactic sugar.
If you don't want a string (that always includes the trailing
'\0') then you can't use a syntax construct that's meant for
initializing with strings. You then need to to use the normal
array initialization syntax, even though it's a bit more cum-
bersome.
So I wanted to know whether I'm just to stupid to see a simple, native
solution or if there none. From the replies I suppose the latter is the
case. But this makes C, at least in my opinion, a poor language.
I think it's neither a question of stupidness or a poor language.
I guess that it's a question of unrealistic expectations. You want
the absolute power of assembler combined with the ease of program-
ming in C. But you can't have the cake and eat it. C allows doing
a lot more of low level stuff than many other languages but there
are limits.
PS:
In my case there wasn't the two integer values but this doesn't
help at all, because the padding is also done when the ascii
text is the last data in the structure.
struct {short b; char c[11];} c={456,"Hello World"};
will report a false sizeof() because of the padding, and a
No, it will report the correct sizeof, it just won't report the
sizeof you want;-) The compiler probably will have to append a
padding byte here to make sure it's possible to have an array
of such structures with each element being properly aligned.
That's something you don't have to care about in assembler
(where you don't have structures) but which is essential in
the context of a C program.
struct {short b; char c[];} c={456,"Hello World"};
will report a false sizeof() because of the zero terminated
string and the padding.
C isn't assembler and it doesn't cater for all the needs you
may have for your assembler-C mix but mostly for the needs
of "sane" C programs (BTW, there's nothing keeping you from
linking together object files created from "clean" C files and
others created from assembler, perhaps that might avoid a few
problems you experience). E.g. having padding bytes within struc-
tures is something the compiler is allowed to do for whatever
reasons it may have, be it enforcing proper alignment or just
speed of access of elements (I guess 99.9% of all people won't
care much about a padding byte or two but a lot about the speed
of their programs, so guess what the compiler writers will favor).
C is not assembler and you have to trade certain elements of
ultrafine control for ease of programming - as it's always the
case.
If you want support for that kind of fine control you have to
check if your compiler has some extensions for that (already
supporting asm() is such an extension). E.g. gcc allows you
to override the default padding of structures etc. But that's
not really part of C but additions beyond C for people like
you that want or need a mixture of assembler and C.
BTW, I am a bit wondering: isn't using the X server kind of
cheating in your quest for absolute, direct control? You don't
want to use Xlib but then you talk to the X server, which also
is just a user land program (and probably also mostly or even
100% written in C). Shouldn't you not also take the X server
out of the loop and issue commands directly to the kernel mo-
dule dealing with the graphics card?
I guess I know what you're after. In my Z80-CP/M days I also
spend lots (make that insane amounts;-) of time trying to
understand how the whole thing works at the lowest level,
learning to read a good deal of the operating systems code
in machine language and e.g. figuring out how to position the
floppy disks head over a certain track or outputting a dot
on a certain position on the screen etc. That was a lot of
fun and I guess I learned quite a bit doing that. It's just
that modern multi-user, multi-tasking systems are a bit too
complex for that kind of games, there's always some limit
how far you can go. My personal impression is that trying to
learn how to control every aspect directly only makes sense
on simple systems like CP/M or DOS (and these systems still
can be used well for that purpose), but with modern systems
this is getting a bit insane, especially since at least some
of them aren't bound to a certain CPU architecture. Nowadays
it's more interesting and rewarding to understand and change
things like the kernel etc., but in a way so that it works on
all (supported) architectures.
Regards, Jens