Linux-Development-Sys Digest #854, Volume #7 Sun, 14 May 00 11:13:20 EDT
Contents:
Re: ANSI C & void main() ("Mark Graybill")
Re: Linux (thread vs fork) (bil@p)
Re: (found it!) /proc/pid/stat array.c question (Eric Taylor)
Re: Linux (thread vs fork) (Eric Taylor)
Can't compile pci-irq.c (Christian =?iso-8859-1?Q?J=F6nsson?=)
Re: ANSI C & void main() (Kaz Kylheku)
Re: ANSI C & void main() (Erik Max Francis)
Re: ANSI C & void main() (Erik Max Francis)
Re: Waiting on two threads (Dan McGuirk)
Re: ANSI C & void main() ("Frank")
"Signal out of range" PCI Riva NV3 framebuffer? (Christian
=?iso-8859-1?Q?J=F6nsson?=)
----------------------------------------------------------------------------
Reply-To: "Mark Graybill" <[EMAIL PROTECTED]>
From: "Mark Graybill" <[EMAIL PROTECTED]>
Subject: Re: ANSI C & void main()
Date: Sun, 14 May 2000 05:55:26 GMT
Ok, this is getting convoluted.
Let's analyze the text in the standard.
"2 An implementation shall not predefine the main function."
This is because the programmer is to define the main function.
"This function shall not be overloaded."
This function doesn't have the same polymorph rights as others. The
implementation defines what it allows for main, not the programmer.
"It shall have a return type of type int, but otherwise its type is
implementation�defined. All implementations
shall allow both of the following definitions of main: int main() { /* ...
*/ } and int main(int argc, char* argv[]) { /* ... */ }"
All implementations must support the int return type with the specified
polymorph prototypes (IOW, a minimum.) But, an implementation can define
and support other types (type of void IS not prohibited by the standard.)
"3 ... The linkage (3.5) of main is implementation�defined."
There is no guideline of how main is linked to the calling code. For
instance, some crt0 code pushes and pops the return code off the stack.
Others saves the return code to a specified memory location. This is
defined by the implementation.
"5 ... If control reaches the end of main without encountering a return
statement, the effect is that of executing
return 0;"
Since you cannot return a value with a return type of void, then paragraph 5
defines the behavior after void main() returns to the calling code.
I'll use Intel CPU instructions to illustrate:
(calling code if compiled with main() returning a value)
...
call [<addr of main>]
pop [ax] ;
retrieve the return code.
mov [<addr to store return code], ax ; store the return code.
...
(calling code if compiled with main() not returning a value; e.g. void
main())
...
call [<addr of main>]
mov ax,0
mov [<addr to store return code], ax
-Mark
------------------------------
From: bil@p
Subject: Re: Linux (thread vs fork)
Date: 14 May 2000 00:46:50 -0700
In article <[EMAIL PROTECTED]>, Vetle says...
>
>* bil@p
>> >I know that Apache uses preforking
>>
>> what is 'preforking' ?
>
>creating new processes before requests arrive. it eliminates the
>overhead of creating a new process when answering a request.
That is strange term to use, who invented it?
This is basically creating a pool of worker processes
(or even pool of threads), to handle incomming requests
on the server socket. I just never heared the term
preforking used in this context.
------------------------------
From: Eric Taylor <[EMAIL PROTECTED]>
Subject: Re: (found it!) /proc/pid/stat array.c question
Date: Sun, 14 May 2000 01:45:16 -0700
Eric Taylor wrote:
>
> hi:
>
> I want to make /proc/pid/stat report the current frame pointer
> on a 386 system. I see two macros used by array.c
>
> #define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned
> long)(tsk)))[1019])
> #define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned
> long)(tsk)))[1022])
>
> which i can't figure out. I tried adding my own for the ebp
> register and set the value of the array from 1015 thru 1025 to
> no avail.
>
> It seems the registers are not saved in the task struct, but
> at the above magic offsets. Can someone explain what that
> code does, and maybe give me a hint as to where i might find
> the saved frame pointer??
>
> thanks
> e
Looks like all the registers are there I just had to be sure
to look back far enough. I Still don't understand why these
are here though.
e
------------------------------
From: Eric Taylor <[EMAIL PROTECTED]>
Subject: Re: Linux (thread vs fork)
Date: Sun, 14 May 2000 01:47:44 -0700
bil@p wrote:
>
> In article <[EMAIL PROTECTED]>, Vetle says...
> >
> >* bil@p
> >> >I know that Apache uses preforking
> >>
> >> what is 'preforking' ?
> >
>
> >creating new processes before requests arrive. it eliminates the
> >overhead of creating a new process when answering a request.
>
> That is strange term to use, who invented it?
> This is basically creating a pool of worker processes
> (or even pool of threads), to handle incomming requests
> on the server socket. I just never heared the term
> preforking used in this context.
I've seen the term used in Stevens book on
unix network programming - I thought he invented it
just for that book - but who knows.
e
------------------------------
From: Christian =?iso-8859-1?Q?J=F6nsson?= <[EMAIL PROTECTED]>
Crossposted-To: linux.dev.kernel
Subject: Can't compile pci-irq.c
Date: Sun, 14 May 2000 09:18:33 GMT
I can't compile pci-irq.c in linux-2.3.99-pre9-1. This is on a Red Hat
Linux 6.2/Intel system.
gcc -D__KERNEL__ -I/usr/src/linux-2.3.99-pre9-1/include -Wall
-Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing
-pipe -march=i686 -c -o pci-irq.o pci-irq.c
pci-irq.c:225: `PCI_DEVICE_ID_INTEL_82440MX_1' undeclared here (not in a
function)
pci-irq.c:225: initializer element for `pirq_routers[3].device' is not
constant
make[1]: *** [pci-irq.o] Error 1
make[1]: Leaving directory
`/usr/src/linux-2.3.99-pre9-1/arch/i386/kernel'
make: *** [_dir_arch/i386/kernel] Error 2
Cheers,
/ChJ
------------------------------
From: [EMAIL PROTECTED] (Kaz Kylheku)
Subject: Re: ANSI C & void main()
Reply-To: [EMAIL PROTECTED]
Date: Sun, 14 May 2000 09:42:05 GMT
On Sun, 14 May 2000 05:55:26 GMT, Mark Graybill <[EMAIL PROTECTED]> wrote:
>Ok, this is getting convoluted.
Only thanks to your and that Frank character's application of Monty Pythonian
logic to the matter. ;)
>Let's analyze the text in the standard.
You don't seem to be quite ready to analyze the text for others. You haven't
read enough of it to have a complete picture and seem to be struggling with the
``standardese'' language which these standards are written in. Also, you are
desperately trying to interpret the wording in a way that salvages your case,
which is not a reasonable approach.
Another problem is that you are looking at the wrong standard. We were are
discussing C, not C++. The subject of this thread is ``ANSI C and void main''
not ``ANSI C++ and void main''. You cannot subsitute one for the other.
Let's look at a draft of C9X (WG14/N843, August 3, 1998)
which is probably very close to the one that was approved by ISO
as the 1999 definition of C:
5.1.2.2.1 Program startup
The function called at program startup is named main. The
implementation declares no prototype for this function. It shall be
defined with a return type of int and no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though
any names may be used, as they are local to the function in which
they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent, or in some other implementation-defined manner.
Okay, now pay attention. The word ``shall'' is used. This is significant,
because in the Standardese language, ``shall'' has a special meaning,
distinct from, say, ``will''.
If we turn to clause 4, we find this:
4. Conformance
[ snip ]
If a ``shall'' or ``shall not'' requirement that appears outside
of a constraint is violated, the behavior is undefined.
Undefined behavior is otherwise indicated in this International
Standard by the words ``undefined behavior'' or by the omission
of any explicit definition of behavior. There is no difference in
emphasis among these three; they describe ``behavior that is
undefined''.
So the standard, in a ``shall'' requirement, has apparently given the
programmer three choices on how to declare main. Either int main(void), int
main(int argc, char **argv) or equivalent, or some other implementation-defined
manner which need not return int.
A naive reading of this would make it seem that the third choice is an escape
hatch that allows the programmer to define this function using any type he or
she wants. Fortunately, this is not the case, otherwise implementations would
have to support all possible monstrosities, like
struct X main(struct Y, struct Z) ...
You see, the alternate form has to be one that is implementation-defined.
Let's jump back to clause 1:
1. Scope
This International Standard specifies the form and establishes
the interpretation of programs written in the C programming language.
The form and interpretation of a program which relies on the presence of an
implementation-defined feature cannot possibly be established by the standard.
It can only be established by the standard plus some other document, such as
your compiler documentation. Your compiler documentation could say,
for instance, that if you declare the program ``void main(void)''
a game of Tetris will pop up on your screen. That's implementation defined!
The behavior of a program is only defined if it the standard establishes an
interpretation for it. That's what defined means.
Finally, although the appendices are not a normative part of the standard,
their contents are telling of what the intent is.
Take a look at appendix K.2, which provides a convenient, though not
exhaustive, summary undefined behaviors:
K.2 Undefined behavior
The behavior is undefined in the following circumstances:
[ snip a few ]
--- A program in a hosted environment does not define a function
main using one of the two specified forms (5.1.2.2.1).
One of the *two* specified forms.
Finaly, note that few compilers actually define void main in their
documentation. So programs which use it are not relying on an documented
extension at all, but rather on an undocumented fluke. The
Conformance clause (4) also states
An implementation shall be accompanied by a document that defines
all implementation-defined and locale-specific characteristics and
all extensions''.
So why does the standard say that there is a third possibility that
main have an implementation-defined form? Simply to make it clear
to implementors that they can provide an alternate startup form if
it makes sense in their environment---that programs don't have to be
rejected on grounds of having other than the two forms.
The committee also wants to avoid restricting freestanding implementations
of the language, which is why you have:
5.1.2.1 Freestanding environment
In a freestanding environment (in which C execution may take place
without any benefit of an operating system), the name and type
of the function called at program startup are implementation-defined.
This perfectly describes Microsoft Windows, where programs commonly start
executing in a function called WinMain, and most certainly run
without any benefit of an operating system. ;)
The ANSI C Rationale written in 1989 states:
As little as possible is said about freestanding environments,
since little is served by constraining them.
So that about covers the topics of defining the startup function.
Does any of it help?
Finally, here is the formal definition of undefined behavior from clause
3, so that you aren't fooled into thinking that an implementation
must do something nice, like stop compiling the program and produce
an error:
3.18
undefined behavior
behavior, opn use of a nonportable or erroneous program construct,
of erroneous data, or of indeterminately valued objects, for
which this International Standard imposes no requirements.
NOTE Possible undefined behavior ranges from ignoring the
situation completely with unpredictable results, to behaving
during translation or program execution in a documented
manner characteristic of the environment (with or without
the issuance of a diagnostic message), to terminating a translation
or execution (with the issuance of a diagnostic message).
The text of the NOTE used to be normative in the 1989 standard, but
now seems to have shifted to just being a clarifying note.
Anyway, this off topic thread has gone on long enough and I'm tired of it, as
I'm sure are readers of comp.os.linux.development.system.
If you remain unconvinced, try your luck in comp.lang.c or comp.std.c.
I hope you own at least half a dozen pairs of asbestos underwear.
--
#exclude <windows.h>
------------------------------
From: Erik Max Francis <[EMAIL PROTECTED]>
Subject: Re: ANSI C & void main()
Date: Sun, 14 May 2000 02:42:27 -0700
Mark Graybill wrote:
> We are talking about both. We use void main(), which is ANSI comliant
> IF
> the implementation allows it; and the implementation (compiler)
> determines
> the behavior after it returns.
No. The implementation is allowed to supply additional support for
varying types of main, _provided_ that it returns int. The relevant
portion of the Standard was recently quoted here (I thought by you), and
unambiguously stated this.
> Regardless of what the compiler allows through as a type of main, if a
> value
> is not returned, the behavior is defined.
If the return type is not int, then the behavior is already undefined,
so anything else that happens is irrelevant.
> The behavior everyone is speaking of is that of post main() execution.
> The
> standard clearly states that if a return statement does not exist in
> main()
> (or a value is not returned), that the implementation shall treat it
> as if a
> "return 0;" was executed.
Which would be great, except that this portion is totally irrelevant.
Earlier the Standard states that the return type must be int, two
argument lists must be supported, and other argument lists may be
included as implementation-defined extensions. The Standard does not
say that a non-int returning main is legal; in fact, it states quite the
opposite. The comment about an implied return 0 when execution runs off
main is a red herring to your goal; that only applies given the other
statements that were involved in defining the type and behavior of main,
and so is only significant with respect to the fact that main must
return int.
Besides, what you're saying is self-contradictory. A main declared to
return void, but which is allowed because there's an implicit return 0
at the end? But it doesn't return int, it returns void -- a return 0
(implicit or not) in a void function is an error.
You need to practice up on your specification reading skills.
--
Erik Max Francis / [EMAIL PROTECTED] / http://www.alcyone.com/max/
__ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/ \ Awards are merely the badges of mediocrity.
\__/ Charles Ives
Erik Max Francis' bookmarks / http://www.alcyone.com/max/links/
A highly categorized list of Web links.
------------------------------
From: Erik Max Francis <[EMAIL PROTECTED]>
Subject: Re: ANSI C & void main()
Date: Sun, 14 May 2000 02:47:17 -0700
Mark Graybill wrote:
> Let's analyze the text in the standard.
As I said earlier, you're flopping back and forth between C and C++.
They're different languages. (Although here they agree, except for the
implicit return stuff at the end of main, which is not relevant to your
point.)
> "It shall have a return type of type int, but otherwise its type is
> implementation�defined. All implementations
> shall allow both of the following definitions of main: int main() {
> /* ...
> */ } and int main(int argc, char* argv[]) { /* ... */ }"
>
> All implementations must support the int return type with the
> specified
> polymorph prototypes (IOW, a minimum.) But, an implementation can
> define
> and support other types (type of void IS not prohibited by the
> standard.)
No. You are not reading it right.
"It shall have a return type of int ..."
main must return int. Period.
"... but otherwise its type is implementation-defined."
But main's argument list can be implementation-defined. That is, an
ANSI-compliant C++ compiler must accept int main(void) and int main(int
argc, char *argv[]). It can also accept other argument lists, _but it
must return int_. This was clearly and explicitly stated by the
Standard, but you missed it.
> "5 ... If control reaches the end of main without encountering a
> return
> statement, the effect is that of executing
> return 0;"
>
> Since you cannot return a value with a return type of void, then
> paragraph 5
> defines the behavior after void main() returns to the calling code.
This is a red herring. It only applies given what the Standard has
stated earlier -- namely, that main must return int. (Besides, a return
0, implicit or not, at the end of a function which returns void is
illegal -- another hint that you're reading this wrong.)
--
Erik Max Francis / [EMAIL PROTECTED] / http://www.alcyone.com/max/
__ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/ \ Awards are merely the badges of mediocrity.
\__/ Charles Ives
Erik Max Francis' bookmarks / http://www.alcyone.com/max/links/
A highly categorized list of Web links.
------------------------------
From: Dan McGuirk <[EMAIL PROTECTED]>
Subject: Re: Waiting on two threads
Date: 14 May 2000 04:30:53 -0700
Brian Lalor <[EMAIL PROTECTED]> writes:
> I'm trying to write a program that spawns two threads and then waits for them
> to finish. The problem is that I don't know ahead of time which thread will
> finish first. As I understand the signaling methodology
> (pthread_cond_signal()), I can only wait on one signal at a time, and spin
> locking just sucks up CPU. Here's a basic layout of what I'm trying to do:
You only want to create one condition variable (and associated mutex),
not two. Your main() waits on the condition variable, and both
threads signal it. You'll have to use some other state to tell which
thread it is that's finished (e.g., you could have 'thread_a_finished'
and 'thread_b_finished' flags, or whatever). When you wake up on the
condition variable in main() the first time, you check which thread is
done, do whatever's appropriate, then wait on the condition variable
again.
--
Dan McGuirk <[EMAIL PROTECTED]>
I'm with the invaders; no use trying to hide that.
------------------------------
From: "Frank" <[EMAIL PROTECTED]>
Subject: Re: ANSI C & void main()
Date: Sun, 14 May 2000 13:54:42 GMT
Kaz Kylheku <[EMAIL PROTECTED]>...
^
^ Only if you apply a sixth grade or lower level of reading
^ comprehension to the text.
Are you applying sixth grade behavior here? To accurately read a standard you
must "apply a sixth grade or lower level of reading comprehension to the
text." If you read anything into it, as adults typically do, you are very
likely creating errors.
Please show me where and how the standard makes 'void main()' noncompliant. I
believe that heretofore we have only seen opposing interpretations.
Frank
------------------------------
From: Christian =?iso-8859-1?Q?J=F6nsson?= <[EMAIL PROTECTED]>
Subject: "Signal out of range" PCI Riva NV3 framebuffer?
Date: Sun, 14 May 2000 14:19:51 GMT
I have a RIVA 128 video card and I have compiled
framebuffers into the kernel. Now, I can't seem to get
it quite right. When I boot linux, the screen goes blank
after a short while and the message "Signal out of range"
appears. Then, the X-server pops and I have a screen
again.
Any hints? Pointers to info on how to get fb working?
TIA,
/ChJ
------------------------------
** FOR YOUR REFERENCE **
The service address, to which questions about the list itself and requests
to be added to or deleted from it should be directed, is:
Internet: [EMAIL PROTECTED]
You can send mail to the entire list (and comp.os.linux.development.system) via:
Internet: [EMAIL PROTECTED]
Linux may be obtained via one of these FTP sites:
ftp.funet.fi pub/Linux
tsx-11.mit.edu pub/linux
sunsite.unc.edu pub/Linux
End of Linux-Development-System Digest
******************************