GCC question

B

Ben Bacarisse

Herbert Kleebauer said:
I mostly don't write programs to get an executable but to learn
something. And you learn most, when you make errors and then
understand why you made this error and why it was an error at all.
I also would like to learn something from your comment, but without
a further explanation I doubt this will be possible.

I'll explain as much as I have time for. Just ask.

My main problems with your program are (a) the use of asm (it stop
being C -- or at the very least t stops being C I can comment on with
confidence); (b) old style declarations -- it is much better to get
the compiler to type-check your function calls; (c) include standard
headers to get prototype of standard functions; and (d) casting to
char * -- void * is usually better as a "generic pointer".
The compiler can prove that x_send is
never called, so I am not surprised you get unexpected results.

Why do you think x_send is never called?

send8.s8y=0;
for (i=1;i<9;i++)
{send8.s8x=0;
for (j=1;j<9;j++)
{if (brett[j]) x_send((char*)&send8, sizeof(send8));
send8.s8x += 50;
}
send8.s8y += 50;
}

x_send is called 64 times, and 64 circles are drawn on the screen.
The problem is, that the x position of the circle is stored in
send8.s8x and the compiler generated code never updates this variable
(send8.s8x += 50;) but instead updates a temporary local variable
(which is WRITE_ONLY!!!) and therefore all circles are drawn on
the same x position. On the other side, send8.s8y is properly
updated (here no temporary local variable is used) so on the
screen is a row of 8 circles displayed.

So, how can "The compiler can prove that x_send is never called"?


It is only called if brett[j] is true (non-zero) but brett is a
file-scope object without an (explicit) initializer. Therefore it is
initialized to zero so there will be no calls.

I doubt this what is happening, but it could be part of the problem.
Can you demonstrate the problem with a program without the asm
construct and with data that causes x_send to be called?
 
K

Kaz Kylheku

But I still think this is an illogical behaviour of GCC even if it,
as pointed out in other replies, doesn't violate the C specification.

Wonderful! But you aren't going to solve any GCC problem by continuing this
off-topic thread in comp.lang.c.

I recently found a real bug in GCC. Do you know what I did? I patched
it. Then I opened up a report in GCC bugzilla, where I described
the problem and uploaded the patch as an attachment. Eventually
the patch went in, as submitted, and the bug was closed.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34456

The comp.lang.c newsgroup didn't have to be involved in any way.

If you think that GCC is generating dead stores even under optimization, now
you know where to take up this issue.
 
C

Chris Torek

(I think this is not the problem; see below.)

It is only called if brett[j] is true (non-zero) but brett is a
file-scope object without an (explicit) initializer. Therefore it is
initialized to zero so there will be no calls.


Presumably there is some code he has not included in the posted
example that changes the array. (The example was meant more as
sample input code generating the sample x86 assembly, not as
something one would actually run.)
Can you demonstrate the problem with a program without the asm
construct and with data that causes x_send to be called?

I think the problem will go away.

Let me re-introduce the important parts of the original code,
replacing the "asm" call with what gcc "sees" from it:

void
x_send(p, n)
char *p;
int n;
{
while (n) {
eax = -11;
const int par[] = { x_handle, (int) p, n, 0};
while (eax == -11) {
int regB;
const int (*regC)[4];

/*
* asm volatile("int $0x80" : "=a"(eax) :
* "0"(102), "b"(9), "c"(&par));
*/
eax = 102; /* in %eax */
regB = 9; /* in %ebx */
regC = &par; /* in %ecx */
eax = rand_ish_int0x80(eax, regB, regC);
/*
* Not really rand(), but the idea is that eax, regB, and
* regC are inputs, and eax is an output, so eax is
* changed by the "call" (the inline asm). Note that
* regB and regC are unchanged after the "call", so they
* are still exactly 9 and &par. All other local variables
* are also unchanged, and -- here is the crucial bit --
* rand_like_function() is assumed not to read or alter
* anything else "live" in memory.
*/
}
if (eax >= -4095)
exit(0);
n -= eax;
p += eax;
}
}

void
display()
{
int i, j;
send8.s8y = 0;
for (i = 1; i < 9; i++) {
send8.s8x = 0;
for (j = 1; j < 9; j++) {
if (brett[j])
x_send((char *)&send8, sizeof(send8));
send8.s8x += 50;
}
send8.s8y += 50;
}
}

GCC expands x_send() in line, and can see that x_send() does not
modify send8.s8x. None of the things x_send() does use the memory
pointed-to by p (the only thing used is the value of p itself,
converted to "int", and because it is so converted, no bytes at *p
can be read, much less altered.

If GCC had not expanded x_send() in line, but simply compiled the
display() function "stand-alone" as it were, it would have assumed
that x_send() might read or even modify the various bytes inside
the send8 structure. That would force it to adjust send8.s8x
inside the loop. But it *did* expand it in-line, and can see that
inside x_send, *p is never read, much less modified. This means
that it is safe to host the modification of send8.s8x outside the
inner loop (or indeed outside both loops -- the modification to
send8.s8y can likewise be hoisted outside the loop).

The problem, assuming inline expansion is to be allowed, is the
"asm". It claims that a few registers are used and modified, but
makes no claims about memory. Simply stating that *p is used should
fix the problem (there are "bigger hammers" available that should
also do it, but making *p an input seems like the minimum required).
But gcc's asm() construct is a GNUC issue, not a Standard C item,
so I did not mention any of this earlier (and in any case the "best"
fix is probably to stop using the asm() construct in the first
place -- among other things, the hardcoded system call number is
wrong on various machines, and it seems a bit silly to restrict
the code to x86).
 
B

Ben Bacarisse

Chris Torek said:
(I think this is not the problem; see below.)

Yes, I though it was not the problem also (though I did not know what
the problem was!).
It is only called if brett[j] is true (non-zero) but brett is a
file-scope object without an (explicit) initializer. Therefore it is
initialized to zero so there will be no calls.


Presumably there is some code he has not included in the posted
example that changes the array. (The example was meant more as
sample input code generating the sample x86 assembly, not as
something one would actually run.)
Can you demonstrate the problem with a program without the asm
construct and with data that causes x_send to be called?

I think the problem will go away.


It certainly went away when I replaced x_send with anything that used
p but there is not way I could have explained why.

<snip more than the OP could reasonably expect in the way of
an explanation!>
 
B

Ben Bacarisse

Chris Torek said:
(I think this is not the problem; see below.)

Yes, I though it was not the problem also (though I did not know what
the problem was!).
It is only called if brett[j] is true (non-zero) but brett is a
file-scope object without an (explicit) initializer. Therefore it is
initialized to zero so there will be no calls.


Presumably there is some code he has not included in the posted
example that changes the array. (The example was meant more as
sample input code generating the sample x86 assembly, not as
something one would actually run.)
Can you demonstrate the problem with a program without the asm
construct and with data that causes x_send to be called?

I think the problem will go away.


It certainly went away when I replaced x_send with anything that used
p but there is not way I could have explained why.

<snip more than the OP could reasonably expect in the way of
an explanation!>
 
S

santosh

Herbert Kleebauer wrote:

PS:

For the socket connection to the X server I have to send a data packet
consiting of a short and 17 characters. What is the correct way to
declare such a data structure in C (I need a pointer to this
structure and it's size) without having to count the number
of characters by hand.

struct {short a; char b[*];}
a={1 {'/','t','m','p','/','.','X','1','1','-','u','n','i','x','/','X','0'}}

gives: warning: GCC does not yet properly implement '[*]' array
declarators The data is generated correctly but sizeof(a) is 2.

As you found out, this is not C but GNU C.
struct {short a; char b[];}
b={1 {'/','t','m','p','/','.','X','1','1','-','u','n','i','x','/','X','0'}}

no warning

You should've got at least one diagnostic. In any case, flexible array
members are specific to C99.
The data is generated correctly but sizeof(b) is 2.

struct {short a; char b[17];}
b={1 {'/','t','m','p','/','.','X','1','1','-','u','n','i','x','/','X','0'}}

The generated data is padded with a zero and therefore sizeof(c) is 20
instead of 19.

So, non of these three versions is really useful.

I'm afraid that there is no portable way generate packed structures. You
will have to investigate whatever implementation specific ways that
your compiler provides for turning off structure padding.
 
W

Willem

Herbert Kleebauer wrote:
) For the socket connection to the X server I have to send a data packet
) consiting of a short and 17 characters. What is the correct way to
) declare such a data structure in C (I need a pointer to this
) structure and it's size) without having to count the number
) of characters by hand.
)
) struct {short a; char b[*];}
) a={1,{'/','t','m','p','/','.','X','1','1','-','u','n','i','x','/','X','0'}}

It is highly probable that you need to send such packets with the 'short'
actually being two bytes (sizeof short is usuially but not always 2),
and more importantly that said short needs to be in network byte order,
you would probably be better off declaring it something like:

unsigned char ab[] = "XX/tmp/.X11-unix/X0";
ab[0] = (a << 8) & 255; ab[1] = a & 255;

Which relieves any worry about padding, endianess and sizeof short.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
S

santosh

Herbert Kleebauer wrote:

[ ... ]
PS:

For the socket connection to the X server I have to send a data packet
consiting of a short and 17 characters. What is the correct way to
declare such a data structure in C (I need a pointer to this
structure and it's size) without having to count the number
of characters by hand.

struct {short a; char b[*];}
a={1 {'/','t','m','p','/','.','X','1','1','-','u','n','i','x','/','X','0'}}

gives: warning: GCC does not yet properly implement '[*]' array
declarators The data is generated correctly but sizeof(a) is 2.


struct {short a; char b[];}
b={1 {'/','t','m','p','/','.','X','1','1','-','u','n','i','x','/','X','0'}}

no warning
The data is generated correctly but sizeof(b) is 2.


struct {short a; char b[17];}
b={1 {'/','t','m','p','/','.','X','1','1','-','u','n','i','x','/','X','0'}}

The generated data is padded with a zero and therefore sizeof(c) is 20
instead of 19.

So, non of these three versions is really useful.

Maybe something like this?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
const char *str = "/tmp/.X11-unix/X0";
unsigned char *p = malloc(strlen(str) + sizeof (short));

*(short*)p = 1;
memcpy(p + sizeof (short), str, strlen(str));
printf("%hd\n", *(short*)p);
printf("%.*s\n", (int)strlen(str), p + sizeof (short));
printf("size = %tu\n", (p + strlen(str) + sizeof (short)) - p);
free(p);
return 0;
}

Note that you wouldn't have to consider all these tricky issues if you
would use the Xlib C interface, instead of talking to the X server
directly.
 
H

Herbert Kleebauer

Willem said:
Herbert Kleebauer wrote:
) For the socket connection to the X server I have to send a data packet
) consiting of a short and 17 characters. What is the correct way to
) declare such a data structure in C (I need a pointer to this
) structure and it's size) without having to count the number
) of characters by hand.
)
) struct {short a; char b[*];}
) a={1,{'/','t','m','p','/','.','X','1','1','-','u','n','i','x','/','X','0'}}

It is highly probable that you need to send such packets with the 'short'
actually being two bytes (sizeof short is usuially but not always 2),

from un.h:

struct sockaddr_un {sa_family_t sun_family; .....

and from socket.h:

typedef unsigned short sa_famil_t;

and more importantly that said short needs to be in network byte order,

No, it is a normal short and for the communication with the X server
you can select between big or little endian.

you would probably be better off declaring it something like:

unsigned char ab[] = "XX/tmp/.X11-unix/X0";
ab[0] = (a << 8) & 255; ab[1] = a & 255;

Now, this is what an assembly programmer really want to avoid: initialize
a compile time known constant at run time.

Which relieves any worry about padding, endianess and sizeof short.

sizeof(ab) still is 20 and not 19. Not because of padding but because of
the string terminating 0.


Anyhow, I have added the C versions of the 32 bit x86 Linux X demos to
the assembly sources: ftp://137.193.64.130/pub/assembler/xlinux.zip

If I understand the spirit of this group correctly, then these C
examples are the absolutely perfect C demos to demonstrate others
how you never ever should write a C program. And for people for
which C isn't a religion but a language to write programs, it shows
the minimum code necessary to do simple graphics at the lowest
level without using any include or library files by directly
communicating with the X server.
 
J

Jens Thoms Toerring

Herbert Kleebauer said:
you would probably be better off declaring it something like:

unsigned char ab[] = "XX/tmp/.X11-unix/X0";
ab[0] = (a << 8) & 255; ab[1] = a & 255;
Now, this is what an assembly programmer really want to avoid: initialize
a compile time known constant at run time.

If you know the value of 'a' already in advance there's nothing
that would keep you from putting it into the initialization. Just
use normal array initialization syntax instead of the short-hand
method of using a string:

unsigned ab[ ] = { 0x13, 0, '/', 't', 'm', 'p', '/', '.', 'X', '1',
'1', '-', 'u', 'n', 'i', 'x', '/', 'X', '0' };

This will give you an array with 19 elements and no trailing '\0'
character.

I don't know what exactky you mean by "initialize a compile time
known constant at run time". If 'ab' is a global array I am rather
sure it will end up in the data section of the program.
sizeof(ab) still is 20 and not 19. Not because of padding but because of
the string terminating 0.

If you do

unsigned char ab[ 19 ] = "XX/tmp/.X11-unix/X0";

then the array will have 19 elements, not 20 (and it won't be
a string anymore since the trailing '\0' will be missing).

Regards, Jens
 
S

santosh

Herbert said:
Willem said:
Herbert Kleebauer wrote:
) For the socket connection to the X server I have to send a data
packet ) consiting of a short and 17 characters. What is the correct
way to ) declare such a data structure in C (I need a pointer to this
) structure and it's size) without having to count the number
) of characters by hand.
)
) struct {short a; char b[*];}
)
a={1 {'/','t','m','p','/','.','X','1','1','-','u','n','i','x','/','X','0'}}

It is highly probable that you need to send such packets with the
'short' actually being two bytes (sizeof short is usuially but not
always 2),

from un.h:

struct sockaddr_un {sa_family_t sun_family; .....

and from socket.h:

typedef unsigned short sa_famil_t;

and more importantly that said short needs to be in network byte
order,

No, it is a normal short and for the communication with the X server
you can select between big or little endian.

you would probably be better off declaring it something like:

unsigned char ab[] = "XX/tmp/.X11-unix/X0";
ab[0] = (a << 8) & 255; ab[1] = a & 255;

Now, this is what an assembly programmer really want to avoid:
initialize a compile time known constant at run time.

Which relieves any worry about padding, endianess and sizeof short.

sizeof(ab) still is 20 and not 19. Not because of padding but because
of the string terminating 0.

Did you see my solution? It's similar to Willem's but meets your
requirements, I think.
Anyhow, I have added the C versions of the 32 bit x86 Linux X demos to
the assembly sources: ftp://137.193.64.130/pub/assembler/xlinux.zip

Excellent. If you want comments on the C aspects of your demos, you can
post them here. Many participants will be unwilling to take the trouble
to download your archive, run the risk of viruses, extract the files,
compile and test them.
If I understand the spirit of this group correctly, then these C
examples are the absolutely perfect C demos to demonstrate others
how you never ever should write a C program.

Huh? Are you saying that your demos would be considered very bad C in
this newsgroup? If so, then why do you come to that conclusion about
your own code? Is it because you knowingly go beyond the guarantees
that Standard C provides, by using extensions? That doesn't necessarily
make the code poor, it's just not very portable, that's all. If OTOH,
you pepper your code with cases of undefined behaviour and leave them
in because they happen to produce desired behaviour on your
implementation, then that's certainly what one *could* call poor code.
Sometimes it is necessary to use a construct that invokes UB, by dire
necessity, but there are almost always better ways.
And for people for
which C isn't a religion but a language to write programs, it shows
the minimum code necessary to do simple graphics at the lowest
level without using any include or library files by directly
communicating with the X server.

Nice, but do announce your demos on other groups too like
comp.os.linux.x, c.o.l.development.apps, comp.unix.programmer etc.
 
H

Herbert Kleebauer

I was unable
to read the programs in question because I couldn't get your link to work
- I am guessing you have a dynamic IP and your address has changed since
you posted the link -


Sorry, it's an old 486 with Linux 1.18 continuously running since 14 years
now (just want to know how long the PC works). But in last time it needs
more often a reboot (especially when Google visit it), But can't do this
before next week.

Here a http mirror of the ftp server: http://www.ikomi.de/pub/

And here the X demos.

http://www.ikomi.de/pub/assembler/xlinux.zip
 
H

Herbert Kleebauer

santosh said:
Herbert Kleebauer wrote:

Did you see my solution? It's similar to Willem's but meets your
requirements, I think.

Seems I didn't correctly express my question. Suppose I want a
_compile_time_ initialized data structure consisting of one int,
one short, a sequence of characters (where I decide whether NULL
terminated (a C string) or not) and again one int (where I decide
whether it is aligned or not). Now you can argue, it doesn't make
much sense to use not aligned integers, but that's not the question.
The compiler can issue a warning that this may result in a speed
penalty or even a run time error, but at least if the target
architecture allows not aligned words (like with the x86), the
compiler should do as it is told to do. The compiler should also
be able to calculate the correct size of the data structure.

This makes a total of four different data structures which easily
can be defined with an assembler:


0000007b a: dc.l 123
01c8 dc.w 456
48 65 6c 6c 6f 20
57 6f 72 6c 64 dc.b "Hello World"
00000315 dc.l 789
sizeof_a = @-a


0000007b b: dc.l 123
01c8 dc.w 456
48 65 6c 6c 6f 20
57 6f 72 6c 64 00 dc.b "Hello World",0
00000315 dc.l 789
sizeof_b = @-b


0000007b c: dc.l 123
01c8 dc.w 456
48 65 6c 6c 6f 20
57 6f 72 6c 64 dc.b "Hello World"
00 00 00 even 4
00000315 dc.l 789
sizeof_c = @-c


0000007b d: dc.l 123
01c8 dc.w 456
48 65 6c 6c 6f 20
57 6f 72 6c 64 00 dc.b "Hello World",0
00 00 even 4
00000315 dc.l 789
sizeof_d = @-d



Now, with GCC I'm only able to generate the last two directly. But even
there I have to manually (which really isn't acceptable) count the number
of characters in the string:

struct {int a; short b; char c[11]; int d;} c={123,456,"Hello World",789};
struct {int a; short b; char c[12]; int d;} d={123,456,"Hello World",789};

which gives:

c:
.long 123
.value 456
.ascii "Hello World"
.zero 3
.long 789
d:
.long 123
.value 456
.string "Hello World"
.zero 2
.long 789

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".


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.



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.

So a

struct {short b; char c[11];} c={456,"Hello World"};

will report a false sizeof() because of the padding, and a

struct {short b; char c[];} c={456,"Hello World"};

will report a false sizeof() because of the zero terminated
string and the padding.
 
F

Flash Gordon

Herbert Kleebauer wrote, On 31/07/08 21:09:
Seems I didn't correctly express my question. Suppose I want a
_compile_time_ initialized data structure consisting of one int,
one short, a sequence of characters (where I decide whether NULL
terminated (a C string) or not) and again one int (where I decide
whether it is aligned or not).

You can't even *define* a structure guaranteed to meet your requirements.
Now you can argue, it doesn't make
much sense to use not aligned integers, but that's not the question.

OK, so you don't care about the reasons C does not provide the
facilities you want. In that case just accept that it does not.
The compiler can issue a warning that this may result in a speed
penalty or even a run time error, but at least if the target
architecture allows not aligned words (like with the x86), the
compiler should do as it is told to do.

It does what it is told. The C language just does not have the ability
to tell it what you want to tell it. Equally well the C language
provides no mechanism to make your computer hover 5 feet above the
ground. Some systems that could be programmed in C *can* hover 5 feet
above the ground under the control of SW.
The compiler should also
be able to calculate the correct size of the data structure.

The compiler does calculate the correct size of all data structures you
can define.

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.

If C can't do what you want then use another language. There are plenty
to choose from. However, not providing a mechanism to do things that
won't work on all targeted systems does not, in my opinion, make it a
poor language.
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.

So a

struct {short b; char c[11];} c={456,"Hello World"};

will report a false sizeof() because of the padding, and a

No, sizeof is reporting the size correctly because the padding is part
of the structure.
struct {short b; char c[];} c={456,"Hello World"};

will report a false sizeof() because of the zero terminated
string and the padding.

No, sizeof reports the size correctly because the termination is part of
the structure.

Not doing what you want does not make sizeof incorrect.

In any case you have already been told that if you use the library
provided for talking to the X server you won't have this problem. The
reason libraries are provided is so that you *don't* have to worry about
all of the details or the things you can't do in C.
 
J

Jens Thoms Toerring

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,201
Latest member
KourtneyBe

Latest Threads

Top