Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

clrscr and UB

27 views
Skip to first unread message

Tak-Shing Chan

unread,
Feb 5, 2002, 5:00:09 PM2/5/02
to
On 5 Feb 2002, Dan Pop wrote:

> If I am not able to see it as code, my translator is not able to see it
> as code either. The standard does not define the behaviour of such code,
> therefore its behaviour is undefined. The only functions that can be
> called without supplying their definitions are the standard library
> functions.

I guess not (C99 5.1.1.1). Here is a typical scenerio:

- First translation unit (clrscr.c) contains clrscr().
- Second translation unit (main.c) contains main().

Step 1: clrscr.c is written in strict ISO C. After a
successful translation, the translated unit is
preserved in a library and the source file removed.

Step 2: one year later, main.c gets compiled and linked with
the library. This time, the translator is unable to
see the source file clrscr.c.

According to my reading, C explicitly allows third-party
libraries such as the one made in step 1 above (provided that
such libraries are translated on the same implementation).

[Cross-posted to comp.std.c.]

Tak-Shing

Dann Corbit

unread,
Feb 5, 2002, 6:11:38 PM2/5/02
to
"Tak-Shing Chan" <es...@city.ac.uk> wrote in message
news:Pine.GSO.4.21.0202052112320.10675-100000@exeter...


They would not be disallowed under undefined behavior. They simply would
not produce behavior defined by the standard.

Let's consider a different scenario. Same machine, same compiler, but we
change compile switches. This time, we use some implementation specific
switch that changes the calling convention to pass via registers. Since
there is no formal name mangling requirement for the C language, we might
have exactly the same entry point names. Is the behavior defined?

Let's consider a 3rd scenario. Same machine, same compiler, but we upgrade.
We were using version x.yy but now we are on version z.qq. Now, the old
compiler referenced symbols that were in the old libraries. So this one
won't even link.

Let's consider a 4th scenario. Same machine, same compiler. The old code
assumes operating system Q, but we have changed our operating system to P.
There are calls to systems services that work differently. There are direct
video writes which go into what is now protected memory.

It does not take much imagination to see where these portable libraries can
possibly break down.

One of the reasons why I think the open source movement has so much momentum
is that the portable library idea only "mostly" works.
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
"The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm


Tak-Shing Chan

unread,
Feb 5, 2002, 7:28:37 PM2/5/02
to
On Tue, 5 Feb 2002, Dann Corbit wrote:

> "Tak-Shing Chan" <es...@city.ac.uk> wrote in message
> news:Pine.GSO.4.21.0202052112320.10675-100000@exeter...
>> On 5 Feb 2002, Dan Pop wrote:
>>
>>> If I am not able to see it as code, my translator is not able to see it
>>> as code either. The standard does not define the behaviour of such code,
>>> therefore its behaviour is undefined. The only functions that can be
>>> called without supplying their definitions are the standard library
>>> functions.
>>
>> I guess not (C99 5.1.1.1). Here is a typical scenerio:
>>
>> - First translation unit (clrscr.c) contains clrscr().
>> - Second translation unit (main.c) contains main().
>>
>> Step 1: clrscr.c is written in strict ISO C. After a
>> successful translation, the translated unit is
>> preserved in a library and the source file removed.
>>
>> Step 2: one year later, main.c gets compiled and linked with
>> the library. This time, the translator is unable to
>> see the source file clrscr.c.
>>
>> According to my reading, C explicitly allows third-party
>> libraries such as the one made in step 1 above (provided that
>> such libraries are translated on the same implementation).

^^^^^^^^^^^^^^^^^^^^^^^^^^


> They would not be disallowed under undefined behavior. They simply would
> not produce behavior defined by the standard.

I would argue that the behaviour above is well-defined.

> Let's consider a different scenario. Same machine, same compiler, but we

> change compile switches. [snip]

Then it is not ``on the same implementation''.

> Let's consider a 3rd scenario. Same machine, same compiler, but we upgrade.

> We were using version x.yy but now we are on version z.qq. [snip]

Then it is not ``on the same implementation''.

> Let's consider a 4th scenario. Same machine, same compiler. The old code
> assumes operating system Q, but we have changed our operating system to P.

> [snip]

Then it is not ``on the same implementation''.

> One of the reasons why I think the open source movement has so much momentum
> is that the portable library idea only "mostly" works.

[OT] Well, but Java programmers would disagree...

Tak-Shing

Dann Corbit

unread,
Feb 5, 2002, 8:02:36 PM2/5/02
to
"Tak-Shing Chan" <es...@city.ac.uk> wrote in message
news:Pine.GSO.4.21.0202060003520.13421-100000@exeter...


Your definition of the same implementation really shows exactly how
non-portable libraries are.

Do you know for certain the switches used to compile every library that you
use? I am sure that the answer is no. Are you absolutely certain that
every library that you use is made with exactly the same version of the
compiler? Including the system libraries that you link in?

Imagine any library from the year 1980. Will you link with it and use it?
I am very sure that it is not going to work, or if it does -- only by some
sort of magnificent accident. The portability of a library file is
temporary at best. Since the information on how it was built is not encoded
into the library itself, it becomes non-portable the moment it is created
(using your own definition).

No wonder (then) that the standards committee did not address the issues
associated with user libraries. Quite frankly, I think that they are
completely insoluble.

James Kuyper Jr.

unread,
Feb 5, 2002, 10:59:34 PM2/5/02
to

The C standard only defines the behavior of an entire program, and only
defines it when the entire program is written in C. The "entire program"
must be considered as including the contents of all non-standard header
files that are #included (when a program #includes a standard header, if
it does so correctly, and is correct in all other regards, then it's the
implementation's responsibility to make sure your code works, regardless
of how it chooses to handle that #inclusion).

If clrscr() is written in some other language, the C standard can't say
anything to constrain the behavior of your program. If it is written in
C, the question of whether the program has defined behavior depends upon
what that source code is. It's quite an ordinary thing to write library
functions which have undefined behavior if called with the wrong
arguments, or called in the wrong context.
I doubt that any function named clrscr() could be written entirely in
strictly conforming code; the C standard doesn't describe screens, nor
how to clear them.

Tak-Shing Chan

unread,
Feb 6, 2002, 5:47:11 AM2/6/02
to
On Tue, 5 Feb 2002, Dann Corbit wrote:

> "Tak-Shing Chan" <es...@city.ac.uk> wrote in message

> news:Pine.GSO.4.21.0202060003520.13421-100000@exeter...


>> Then it is not ``on the same implementation''.
>

> Your definition of the same implementation really shows exactly how
> non-portable libraries are.
>

> [snip]


>
> Imagine any library from the year 1980. Will you link with it and use it?
> I am very sure that it is not going to work, or if it does -- only by some
> sort of magnificent accident. The portability of a library file is
> temporary at best. Since the information on how it was built is not encoded
> into the library itself, it becomes non-portable the moment it is created
> (using your own definition).

The information is not encoded but could be documented.
Anyway, libraries are non-portable by default--they can only be
used on the same implementation and nowhere else.

> No wonder (then) that the standards committee did not address the issues
> associated with user libraries. Quite frankly, I think that they are
> completely insoluble.

It is soluble but is outside the scope of C. If we could
extend the ELF format to include all relevant information...

Tak-Shing

Tak-Shing Chan

unread,
Feb 6, 2002, 5:55:41 AM2/6/02
to
On Wed, 6 Feb 2002, James Kuyper Jr. wrote:

> Tak-Shing Chan wrote:
>> Step 1: clrscr.c is written in strict ISO C. After a
>> successful translation, the translated unit is
>> preserved in a library and the source file removed.
>

> [snip]


>
> I doubt that any function named clrscr() could be written entirely in
> strictly conforming code; the C standard doesn't describe screens, nor
> how to clear them.

What about void clrscr(void) {}? It is strictly-conforming,
although it is not doing what you think it does.

Tak-Shing

Peter Nilsson

unread,
Feb 6, 2002, 6:26:38 AM2/6/02
to
"Tak-Shing Chan" <es...@city.ac.uk> wrote in message
news:Pine.GSO.4.21.0202061010360.21042-100000@exeter...

Elements of Chemistry now!

Wasn't setting CHAR_BIT to Avogadro's Number bizarre enough!! ;)

--
Peter


James Kuyper Jr.

unread,
Feb 6, 2002, 7:54:01 AM2/6/02
to

Sorry - I phrased that badly. What I meant to says is that "Any
function named clrscr() is likely to be intended to do something that
cannot be written in strictly conforming code."

If all of the code for your program, including clrscr.c, is written in
C, and if it's all translated and executed by the same implementation of
C, and if that code as a whole constitutes a program with no undefined
behavior, then you won't have that kind of problem. It doesn't matter
whether the code for clrscr.c has since been removed, but it does
matter, very much, what that code actually said.

Whether or not a program that calls clrscr() is conforming can, in
principle, depend upon interactions between clrscr.c and the rest of
your program. The simplest example would be if clrscr.c defines any name
with external linkage in addition to clrscr() itself, and your program
chooses to define that same name, also with external linkage. There's
lots of far more subtle ways they can interact.

Jos A. Horsmeier

unread,
Feb 6, 2002, 10:09:20 AM2/6/02
to
"James Kuyper Jr." <kuy...@wizard.net> wrote in message
news:3C612845...@wizard.net...

> Tak-Shing Chan wrote:
> > On Wed, 6 Feb 2002, James Kuyper Jr. wrote:
> > > Tak-Shing Chan wrote:

> > >> Step 1: clrscr.c is written in strict ISO C. After a
> > >> successful translation, the translated unit is
> > >> preserved in a library and the source file removed.

> > > I doubt that any function named clrscr() could be written entirely in


> > > strictly conforming code; the C standard doesn't describe screens, nor
> > > how to clear them.

> > What about void clrscr(void) {}? It is strictly-conforming,
> > although it is not doing what you think it does.

> Sorry - I phrased that badly. What I meant to says is that "Any
> function named clrscr() is likely to be intended to do something that
> cannot be written in strictly conforming code."

This is totally silly of course, but the best I can come up with is:

void clrscr() {

unsigned int i;

for (i= 0; ++i; )
puts("\r\n");
}

but then again, the entire topic is silly.

kind regards,

Jos aka j...@gen.nl

Dan Pop

unread,
Feb 6, 2002, 12:11:09 PM2/6/02
to
In <Pine.GSO.4.21.0202052112320.10675-100000@exeter> Tak-Shing Chan <es...@city.ac
.uk> writes:

>On 5 Feb 2002, Dan Pop wrote:
>
>> If I am not able to see it as code, my translator is not able to see it
>> as code either. The standard does not define the behaviour of such code,
>> therefore its behaviour is undefined. The only functions that can be
>> called without supplying their definitions are the standard library
>> functions.
>
> I guess not (C99 5.1.1.1). Here is a typical scenerio:
>
> - First translation unit (clrscr.c) contains clrscr().
> - Second translation unit (main.c) contains main().
>

> Step 1: clrscr.c is written in strict ISO C. After a
> successful translation, the translated unit is
> preserved in a library and the source file removed.
>

> Step 2: one year later, main.c gets compiled and linked with
> the library. This time, the translator is unable to
> see the source file clrscr.c.

At this point, what part of the standard defines the behaviour of the
program calling clrscr()?

The behaviour of the function became undefined the very moment its
source file was removed, because you could no longer use the standard
to figure out what the behaviour was (UB by lack of specification).

> According to my reading, C explicitly allows third-party
>libraries such as the one made in step 1 above (provided that
>such libraries are translated on the same implementation).

And provided that the source code is available, so that the standard can
provide a definition of behaviour for the code contained in the libraries.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Dan...@ifh.de

Tak-Shing Chan

unread,
Feb 6, 2002, 3:50:44 PM2/6/02
to
On 6 Feb 2002, Dan Pop wrote:

> In <Pine.GSO.4.21.0202052112320.10675-100000@exeter> Tak-Shing Chan <es...@city.ac
> .uk> writes:
>
>>On 5 Feb 2002, Dan Pop wrote:
>>
>>> If I am not able to see it as code, my translator is not able to see it
>>> as code either. The standard does not define the behaviour of such code,
>>> therefore its behaviour is undefined. The only functions that can be
>>> called without supplying their definitions are the standard library
>>> functions.
>>
>> I guess not (C99 5.1.1.1). Here is a typical scenerio:
>>
>> - First translation unit (clrscr.c) contains clrscr().
>> - Second translation unit (main.c) contains main().
>>
>> Step 1: clrscr.c is written in strict ISO C. After a
>> successful translation, the translated unit is
>> preserved in a library and the source file removed.
>>
>> Step 2: one year later, main.c gets compiled and linked with
>> the library. This time, the translator is unable to
>> see the source file clrscr.c.
>
> At this point, what part of the standard defines the behaviour of the
> program calling clrscr()?

Bad question. C99 5.1.1.1p1, cited above, explicitly define
the behaviour of separately translated translation units
preserved in libraries.

> The behaviour of the function became undefined the very moment its
> source file was removed, because you could no longer use the standard
> to figure out what the behaviour was (UB by lack of specification).

See above.

Tak-Shing

Dann Corbit

unread,
Feb 6, 2002, 4:59:53 PM2/6/02
to
"Tak-Shing Chan" <es...@city.ac.uk> wrote in message
news:Pine.GSO.4.21.0202062039030.17577-100000@exeter...

> On 6 Feb 2002, Dan Pop wrote:
[snip]

> > At this point, what part of the standard defines the behaviour of the
> > program calling clrscr()?
>
> Bad question. C99 5.1.1.1p1, cited above, explicitly define
> the behaviour of separately translated translation units
> preserved in libraries.

Let's take a look:

"5.1.1.1 Program structure
1 A C program need not all be translated at the same time. The text of the
program is kept in units called source files, (or preprocessing files) in
this International Standard. A source file together with all the headers and
source files included via the preprocessing directive #include is known as a
preprocessing translation unit. After preprocessing, a preprocessing
translation unit is called a translation unit. Previously translated
translation units may be preserved individually or in libraries. The
separate translation units of a program communicate by (for example) calls
to functions whose identifiers have external linkage, manipulation of
objects whose identifiers have external linkage, or manipulation of data
files. Translation units may be separately translated and then later linked
to produce an executable program.
Forward references: linkages of identifiers (6.2.2), external definitions
(6.9), preprocessing directives (6.10)."

Not once in this passage do we find terms like "shall" or "shall not."

Under section 4, Conformance, we find this:
"1 In this International Standard, ''shall'' is to be interpreted as a
requirement on an implementation or on a program; conversely, ''shall not''
is to be interpreted as a prohibition.

2 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 all describe ''behavior
that is undefined''."

It is my opinion that 5.1.1.1 places no restrictions on program behavior.
It is only showing what a possible behavior for some implementations might
be like. Further [IMO], definition of the behavior of object libraries
would be impossible to achieve, considering that there is no standard that
governs the behavior of object libraries.

Geoff Field

unread,
Feb 6, 2002, 8:01:13 PM2/6/02
to

"Jos A. Horsmeier" <j.a.ho...@wanadoo.nl> wrote in message
news:a3rgr2$2n4p$1...@scavenger.euro.net...

Ah! An infinite blocking function! Would this be how it's implemented on
the Deathstation 9000?

> but then again, the entire topic is silly.

As is the implementation above ;-)

Geoff

--
Geoff Field, Professional geek, amateur stage-levelling gauge.
Spamtraps: geoff...@hotmail.com, gcf...@bigmailbox.net, or
geoff...@great-atuin.co.uk; Real Email: gcfield at optusnet dot com dot
au
My band's web page: http://www.geocities.com/southernarea/


James Kuyper Jr.

unread,
Feb 6, 2002, 8:37:34 PM2/6/02
to
Geoff Field wrote:
>
> "Jos A. Horsmeier" <j.a.ho...@wanadoo.nl> wrote in message
> news:a3rgr2$2n4p$1...@scavenger.euro.net...
...

> > void clrscr() {
> >
> > unsigned int i;
> >
> > for (i= 0; ++i; )
> > puts("\r\n");
> > }
>
> Ah! An infinite blocking function! Would this be how it's implemented on

UINT_MAX is infinite?

Daniel Fox

unread,
Feb 6, 2002, 8:40:27 PM2/6/02
to

"Geoff Field" <geoff...@hotmail.com> wrote in message
news:10130436...@cswreg.cos.agilent.com...

> > void clrscr() {
> >
> > unsigned int i;
> >
> > for (i= 0; ++i; )
> > puts("\r\n");
> > }
>
> Ah! An infinite blocking function! Would this be how it's implemented on
> the Deathstation 9000?

Unsigned integers will wrap; this for loop will eventually terminate.

-Daniel

Geoff Field

unread,
Feb 6, 2002, 9:46:23 PM2/6/02
to
"Daniel Fox" <danielfox200...@hotmail.com> wrote in message
news:uTk88.102450$E4.39...@e3500-atl2.usenetserver.com...

Of course, you and James Kuyper, Jr are both correct. I missed the fact
that
the ++i was, in fact, in the part of the "for" construct where the
expression is
evaluated. If the loop had read "for (i = 0; ; ++i)" then we would have had
a
DS9000 implementation.

All I can say is "D'oh!"

Tak-Shing Chan

unread,
Feb 7, 2002, 12:29:39 PM2/7/02
to
On Wed, 6 Feb 2002, Dann Corbit wrote:

> It is my opinion that 5.1.1.1 places no restrictions on program behavior.

It does, if you read it in context. The restriction is the
rest of the Standard, which would apply to the said libraries.

> It is only showing what a possible behavior for some implementations might
> be like. Further [IMO], definition of the behavior of object libraries
> would be impossible to achieve, considering that there is no standard that
> governs the behavior of object libraries.

There is no such thing as ``possible behaviour for
implementations'' nor ``behaviour of object libraries''. In C,
programs have behaviours, implementations have not.

Tak-Shing

Dan Pop

unread,
Feb 7, 2002, 1:07:26 PM2/7/02
to
In <Pine.GSO.4.21.0202062039030.17577-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:

>On 6 Feb 2002, Dan Pop wrote:
>
>> In <Pine.GSO.4.21.0202052112320.10675-100000@exeter> Tak-Shing Chan <es...@city.ac
>> .uk> writes:
>>
>>>On 5 Feb 2002, Dan Pop wrote:
>>>
>>>> If I am not able to see it as code, my translator is not able to see it
>>>> as code either. The standard does not define the behaviour of such code,
>>>> therefore its behaviour is undefined. The only functions that can be
>>>> called without supplying their definitions are the standard library
>>>> functions.
>>>
>>> I guess not (C99 5.1.1.1). Here is a typical scenerio:
>>>
>>> - First translation unit (clrscr.c) contains clrscr().
>>> - Second translation unit (main.c) contains main().
>>>
>>> Step 1: clrscr.c is written in strict ISO C. After a
>>> successful translation, the translated unit is
>>> preserved in a library and the source file removed.
>>>
>>> Step 2: one year later, main.c gets compiled and linked with
>>> the library. This time, the translator is unable to
>>> see the source file clrscr.c.
>>
>> At this point, what part of the standard defines the behaviour of the
>> program calling clrscr()?
>
> Bad question. C99 5.1.1.1p1, cited above, explicitly define
>the behaviour of separately translated translation units
>preserved in libraries.

Only to the extent that their source code is available.

Imagine that you have compiled the "hello world" program and have
removed its source file. You no longer have a C program and, therefore,
the C standard can no longer define its behaviour.

This also applies to the case when only some parts of the source code
are no longer available.

Tak-Shing Chan

unread,
Feb 7, 2002, 1:37:32 PM2/7/02
to
On 7 Feb 2002, Dan Pop wrote:

> Only to the extent that their source code is available.

The source code is available during translation time, which
is all that we need. 5p1 says that translation environment and
execution environment are two separate environments. See also
translation phase 8.

Tak-Shing

Dan Pop

unread,
Feb 7, 2002, 1:12:09 PM2/7/02
to
In <Pine.GSO.4.21.0202071710190.22110-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:

> There is no such thing as ``possible behaviour for
>implementations'' nor ``behaviour of object libraries''. In C,
>programs have behaviours, implementations have not.

But a C program consists exclusively of source code, regardless of how it
is translated. If some of its source code is missing, the C program is
no longer complete and its behaviour is no longer defined by the
standard.

William D. Tallman

unread,
Feb 8, 2002, 2:07:12 AM2/8/02
to
Tak-Shing Chan wrote:

I don't have a copy of the final standards. Did they change 4.2? If not,
then I'd really like to know where in C99 5.1.1.1p1 (or anywhere else, for
that matter) is 4.2 explicitly superceded? If the standard doesn't
explicitly define it, is it not then by definition UB?

I would think that if there were any exceptions to 4.2, they would be
identified as such, and I've found no such in the draft copy. Does such an
exemption or supercession exist in the final standards? If so, would
someone please cite it? It would seem that this is a profound issue.....

Confused newbie would appreciate a resolution here.... <grin>

Thanks,

Bill Tallman

Dan Pop

unread,
Feb 8, 2002, 4:32:25 AM2/8/02
to

I can't see anything relevant there.

This International Standard specifies the form and
establishes the interpretation of programs expressed in the
programming language C.

If you don't have the (full) C program, the standard cannot specify its
behaviour. And this means undefined behaviour. If you disagree, please
specify the behaviour of the following C program, according to the
C standard:

unsigned sleep(unsigned);

int main()
{
sleep(1);
return 0;
}

As far as I can see, there is nothing unspecified or implementation
defined in this program, so its behaviour MUST be either well defined
(in which case we have a strictly conforming program) or undefined.

Tak-Shing Chan

unread,
Feb 8, 2002, 6:05:08 AM2/8/02
to
On 7 Feb 2002, Dan Pop wrote:

> In <Pine.GSO.4.21.0202071710190.22110-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
>
>> There is no such thing as ``possible behaviour for
>>implementations'' nor ``behaviour of object libraries''. In C,
>>programs have behaviours, implementations have not.
>
> But a C program consists exclusively of source code, regardless of how it
> is translated. If some of its source code is missing, the C program is
> no longer complete and its behaviour is no longer defined by the
> standard.

The point that you have repeatedly missed, is that what
happens to the C program *physically* is outside of the scope of
the Standard (3p2). AFAIK, C programs can be written on a cake
and the translator can eat the cake as part of the translation
process.

Tak-Shing

Tak-Shing Chan

unread,
Feb 8, 2002, 6:13:16 AM2/8/02
to
On 8 Feb 2002, Dan Pop wrote:

> In <Pine.GSO.4.21.0202071818400.24938-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
>
>>On 7 Feb 2002, Dan Pop wrote:
>>
>>> Only to the extent that their source code is available.
>>
>> The source code is available during translation time, which
>>is all that we need. 5p1 says that translation environment and
>>execution environment are two separate environments. See also
>>translation phase 8.
>
> I can't see anything relevant there.
>
> This International Standard specifies the form and
> establishes the interpretation of programs expressed in the
> programming language C.
>
> If you don't have the (full) C program, the standard cannot specify its
> behaviour. And this means undefined behaviour. If you disagree, please
> specify the behaviour of the following C program, according to the
> C standard:

Can you do better than straw-man attacks? In my original
example, the complete C program (clrscr.c and main.c) is
available during translation. Your example is not.

Tak-Shing

Tak-Shing Chan

unread,
Feb 8, 2002, 6:52:25 AM2/8/02
to
On Fri, 8 Feb 2002, Tak-Shing Chan wrote:

> The point that you have repeatedly missed, is that what
> happens to the C program *physically* is outside of the scope of
> the Standard (3p2). AFAIK, C programs can be written on a cake
> and the translator can eat the cake as part of the translation
> process.

Typo: 1p2.

Tak-Shing

Dan Pop

unread,
Feb 8, 2002, 6:51:13 AM2/8/02
to

What makes you think so? sleep.c was compiled one year ago and removed
after that, just as clrscr.c in your original example.

So, please provide a proper answer to my question.

James Kuyper Jr.

unread,
Feb 8, 2002, 8:02:06 AM2/8/02
to
Dan Pop wrote:
>
> In <Pine.GSO.4.21.0202081105360.9523-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
>
> >On 8 Feb 2002, Dan Pop wrote:
...

> > Can you do better than straw-man attacks? In my original
> >example, the complete C program (clrscr.c and main.c) is
> >available during translation. Your example is not.
>
> What makes you think so? sleep.c was compiled one year ago and removed
> after that, just as clrscr.c in your original example.

Therefore, every part of the entire C program was available, at the
times when it needed to be available. The fact that it wasn't all
available at the same time is irrelevant. If you believe otherwise,
please cite the text that says so.

Tak-Shing Chan

unread,
Feb 8, 2002, 8:08:34 AM2/8/02
to
On 8 Feb 2002, Dan Pop wrote:

> In <Pine.GSO.4.21.0202081105360.9523-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
>> Can you do better than straw-man attacks? In my original
>>example, the complete C program (clrscr.c and main.c) is
>>available during translation. Your example is not.
>
> What makes you think so? sleep.c was compiled one year ago and removed
> after that, just as clrscr.c in your original example.

In that case, the behaviour of the complete program is
defined by the rest of the Standard (5.1.1.1p1). Whether sleep.c
is *physically* present during the separate translation of main.c
is irrelevant to the complete program's behaviour and is outside
of the Standard's scope (1p2).

Tak-Shing

Dan Pop

unread,
Feb 8, 2002, 12:36:26 PM2/8/02
to

I have already done it, upthread. If you don't have access to the
sources NOW, the standard does not define the behaviour of your
program, because there is no way to tell what the parts without source
code are doing. Undefined behaviour by lack of specification.

Consider the case of a translated C program whose source code no
longer exists. What does the C standard guarantee about the behaviour
of this program?

Dan Pop

unread,
Feb 8, 2002, 12:40:17 PM2/8/02
to
In <Pine.GSO.4.21.0202081303100.15560-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:

>On 8 Feb 2002, Dan Pop wrote:
>
>> In <Pine.GSO.4.21.0202081105360.9523-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
>>> Can you do better than straw-man attacks? In my original
>>>example, the complete C program (clrscr.c and main.c) is
>>>available during translation. Your example is not.
>>
>> What makes you think so? sleep.c was compiled one year ago and removed
>> after that, just as clrscr.c in your original example.
>
> In that case, the behaviour of the complete program is
>defined by the rest of the Standard (5.1.1.1p1).

Please elaborate. I can't see anything in the standard defining the
behaviour of a piece of translated code whose source is no longer
available. As far as I can see, the standard deals exclusively in terms
of source code, no matter how it is translated. Therefore, in the
absence of source code, the standard can't define anything.

Tak-Shing Chan

unread,
Feb 8, 2002, 1:51:39 PM2/8/02
to
On 8 Feb 2002, Dan Pop wrote:

> In <Pine.GSO.4.21.0202081303100.15560-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
>> In that case, the behaviour of the complete program is
>>defined by the rest of the Standard (5.1.1.1p1).
>
> Please elaborate. I can't see anything in the standard defining the
> behaviour of a piece of translated code whose source is no longer
> available. As far as I can see, the standard deals exclusively in terms
> of source code, no matter how it is translated. Therefore, in the
> absence of source code, the standard can't define anything.

Source code is completely irrelevant. The Standard deals
exclusively in terms of a C program (an abstract entity), not in
terms of physical source files. The mechanism by which C
programs are transformed for use by a data-processing system is

Dann Corbit

unread,
Feb 8, 2002, 2:55:30 PM2/8/02
to
"Tak-Shing Chan" <es...@city.ac.uk> wrote in message
news:Pine.GSO.4.21.0202081839030.1092-100000@exeter...
> On 8 Feb 2002, Dan Pop wrote:
>
> > In <Pine.GSO.4.21.0202081116140.10757-100000@exeter> Tak-Shing Chan
<es...@city.ac.uk> writes:
> >
> >> The actual behaviour of the libraries themselves are outside

> >>the scope of the Standard
> >
> > Huh?
> >>(1p2, mechanisms by which C programs are transformed and invoked),
> >
> > This is completely irrelevant to the discussion, nobody cared about
> > these mechanisms. You are confusing the behaviour of the code contained
> > in the libraries with the mechanisms by which the libraries have been
> > created.
>
> These mechanisms are very relevant. Go and learn the
> differences between a source file and a C program (5p1;
> 5.1.1.1p1) before you continue.
>
> >>so you cannot say ``undefined by omission''.
> >
> > Of course you can: no source code, no definition of behaviour.
>
> Nonsense. Go and learn the differences between a source
> file and a C program (5p1; 5.1.1.1p1).

Where you see the words "source file" read "translation unit". I think it
goes without saying that a translation unit is a human-readable entity. A
collection of translation units makes up a C program. These translation
units may also reference C language headers which may or may not be "source
files" as well [they could be completely internal to the compiler in the
case of system headers].

If you are arguing that object files are portable C and always present well
defined behavior then I will say this:
If the standard says they are portable then the standard is wrong. Period.
Object files, even on a single system are not reliable after a short period
of time. So, even if the standard does (by some strange interpretation)
insist that they are portable and that their use results in clearly defined
behavior, they are not. Object files and object libraries are clearly
temporal entities. As they age, the probability of them working correctly
degenerates in an exponential manner. A 20 year old object file is almost
surely going to fail. A ten year old object file is very likely to fail. A
five year old object file will probably work. A ten minute old object file
is almost surely going to work. The same thing is not true of a conforming
C file. A conforming C file can be used at any time and does not degrade,
unless it uses features that become obsolete (at which time it is no longer
conforming).

I doubt very much if the ANSI or ISO C standard directly states that objects
and libraries are portable and their use results in defined behavior
anywhere. If it does, then the standard is "full of beans."

So, folks on news:comp.std.c -- I would like an interpretation. Does the C
Standard officially bless object files as conforming inputs to a C program?
Surely it must do so in the special case of the C compiler's library itself.
But what about the case of some arbitrary user object files or object
libraries obtained from 3rd parties?

Barry Margolin

unread,
Feb 8, 2002, 3:35:54 PM2/8/02
to
In article <a41a8...@enews2.newsguy.com>,

Dann Corbit <dco...@connx.com> wrote:
>If you are arguing that object files are portable C and always present well
>defined behavior then I will say this:
>If the standard says they are portable then the standard is wrong. Period.
>Object files, even on a single system are not reliable after a short period
>of time. So, even if the standard does (by some strange interpretation)

How short? The standard doesn't say, so by your logic they could be
unreliable 30 seconds after they're created, which is obviously ludicrous.

>insist that they are portable and that their use results in clearly defined
>behavior, they are not. Object files and object libraries are clearly
>temporal entities. As they age, the probability of them working correctly
>degenerates in an exponential manner. A 20 year old object file is almost
>surely going to fail. A ten year old object file is very likely to fail. A
>five year old object file will probably work. A ten minute old object file
>is almost surely going to work. The same thing is not true of a conforming
>C file. A conforming C file can be used at any time and does not degrade,
>unless it uses features that become obsolete (at which time it is no longer
>conforming).

Most implementors try hard to provide backward compatibility, so that
programs compiled in the past continue to work in future versions of the
OS, and old object files and libraries can be linked into new ones. I've
got an X application that I compiled almost 10 years ago when I was at a
previous employer. I compiled it under SunOS 4.x and it still works under
Solaris 2.6. This level of backward compatibility is not unusual, since
many sites don't have source code to the applications they run, and OS
vendors want them to upgrade.

None of this is required by the C standard of course. Essentially, the way
that object files and libraries are used is beyond its scope.

>I doubt very much if the ANSI or ISO C standard directly states that objects
>and libraries are portable and their use results in defined behavior
>anywhere. If it does, then the standard is "full of beans."

The object files themselves are not portable, but the concept of using them
is not, and the C standard makes explicit reference to this.

>So, folks on news:comp.std.c -- I would like an interpretation. Does the C
>Standard officially bless object files as conforming inputs to a C program?
>Surely it must do so in the special case of the C compiler's library itself.
>But what about the case of some arbitrary user object files or object
>libraries obtained from 3rd parties?

Object files and libraries are part of the mechanism that one uses to
execute a C program when using a compiler-based implementation (as opposed
to an interpreter). The details of invoking the compiler and executing the
result are implementation-dependent. The C standard blesses them as much
as it blesses the command line options you have to use to ensure that the
compiler is being run in ANSI-conformant mode.

--
Barry Margolin, bar...@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Dann Corbit

unread,
Feb 8, 2002, 3:55:08 PM2/8/02
to
"Barry Margolin" <bar...@genuity.net> wrote in message
news:JEW88.69$R16.120973@burlma1-snr2...

> In article <a41a8...@enews2.newsguy.com>,
> Dann Corbit <dco...@connx.com> wrote:
> >If you are arguing that object files are portable C and always present
well
> >defined behavior then I will say this:
> >If the standard says they are portable then the standard is wrong.
Period.
> >Object files, even on a single system are not reliable after a short
period
> >of time. So, even if the standard does (by some strange interpretation)
>
> How short? The standard doesn't say, so by your logic they could be
> unreliable 30 seconds after they're created, which is obviously ludicrous.

Nice straw man. Right below, I explain myself.

That is very, very unusal. Look at most other systems. E.g. OpenVMS (20
years ago would be VMS) used to run on VAX CISC chips and now runs on Alpha
RISC chps. 20 years ago, MS DOS was just born, and ran on 8 bit 8088 chips.
In other words, very little objects that are 20 years old will run. 10 year
old stuff has a decent chance of running (but not great)

> None of this is required by the C standard of course. Essentially, the
way
> that object files and libraries are used is beyond its scope.
>
> >I doubt very much if the ANSI or ISO C standard directly states that
objects
> >and libraries are portable and their use results in defined behavior
> >anywhere. If it does, then the standard is "full of beans."
>
> The object files themselves are not portable, but the concept of using
them
> is not, and the C standard makes explicit reference to this.

I assume that you mean ".. but the concept of using them is .." since
otherwise the above sentence runs contrary to your other discussion.

> >So, folks on news:comp.std.c -- I would like an interpretation. Does the
C
> >Standard officially bless object files as conforming inputs to a C
program?
> >Surely it must do so in the special case of the C compiler's library
itself.
> >But what about the case of some arbitrary user object files or object
> >libraries obtained from 3rd parties?
>
> Object files and libraries are part of the mechanism that one uses to
> execute a C program when using a compiler-based implementation (as opposed
> to an interpreter). The details of invoking the compiler and executing
the
> result are implementation-dependent. The C standard blesses them as much
> as it blesses the command line options you have to use to ensure that the
> compiler is being run in ANSI-conformant mode.

Does the standard say that the implementation must define the behavior as
you claim?

Where? Chapter and verse?

Barry Margolin

unread,
Feb 8, 2002, 6:43:01 PM2/8/02
to
In article <a41do...@enews2.newsguy.com>,

Dann Corbit <dco...@connx.com> wrote:
>That is very, very unusal. Look at most other systems. E.g. OpenVMS (20
>years ago would be VMS) used to run on VAX CISC chips and now runs on Alpha
>RISC chps. 20 years ago, MS DOS was just born, and ran on 8 bit 8088 chips.
>In other words, very little objects that are 20 years old will run. 10 year
>old stuff has a decent chance of running (but not great)

I think you'll find that many programs written for MS-DOS 20 years ago will
still run on Windows. The chip manufacturers also tend to be backward
compatible -- the Pentium instruction set is a superset of the 8086
instruction set.

I'm still running some programs on my Apple iBook that were written for
Macintosh 10 years ago. Apple went so far as to put 68000 emulation into
their Power Macintosh series of systems to ensure backward compatibility.

>Does the standard say that the implementation must define the behavior as
>you claim?
>
>Where? Chapter and verse?

The standard says that separate compilation is possible. What else could
that mean other than that you can link the resulting object files together?

James Kuyper Jr.

unread,
Feb 8, 2002, 7:47:43 PM2/8/02
to
Dan Pop wrote:
...

> available. As far as I can see, the standard deals exclusively in terms
> of source code, no matter how it is translated. ...

Yes, but source code is only needed during translation phase one, and is
no longer relevant for any given translation unit once that phase has
completed.

> ... Therefore, in the


> absence of source code, the standard can't define anything.

In the complete absence of source code, yes. However, the removal of the
source code after translation phase 1 has completed for each translation
unit, is something quite different from the complete absence of source
code.

James Kuyper Jr.

unread,
Feb 8, 2002, 8:12:54 PM2/8/02
to
Dan Pop wrote:

> In <3C63CD50...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:

...

>> times when it needed to be available. The fact that it wasn't all
>> available at the same time is irrelevant. If you believe otherwise,
>> please cite the text that says so.
>
>
> I have already done it, upthread. If you don't have access to the

I didn't notice any citation that appeared to be relevant to that claim.
Could you at least give the section number?

> sources NOW, the standard does not define the behaviour of your
> program, because there is no way to tell what the parts without source
> code are doing.

If an implementation supports seperate compilation, it must store the
translated translation unit in some fashion. Whatever medium it chooses
for that purpose (object files, possibly grouped together into a
library, are the only medium I've ever heard of) must contain all of the
information needed to link the program together and execute it; the
source code no longer needs to exist at that time.

In fact, it would be perfectly legal for an interactive C compiler to be
used, which parsed a translation unit as it is typed in, discarding any
parts it no longer needed, as soon as it no longer needed them, so that
the complete translation unit was never stored as such in memory or on
disk at any time. Such an implementation would be essentially unusuable
by human beings, but it would be legal.

>Undefined behaviour by lack of specification.

Yes, lack of specification is one of the listed ways in which the
behavior can be undefined. However, you have to be very careful about
invoking that option. For example, the standard says absolutely nothing
about hamburgers, or my brother, or eating. Does that mean that my
program has undefined behavior if translated or executed while my
brother is eating a hamburger? True; the standard does not define the
behavior of my brother, or of the hamburger, but the behavior of my
program remains just as well defined as it would have been if he hadn't
eaten the hamburger.

Sure, the behavior of the file system containing the source code is
undefined by the C standard, once the source code is erased. For
instance, the C standard says nothing about the fact that a directory
listing would no longer reflect the presence of that file. However, the
behavior of the translated code remains just as well defined as it was
when the source code was still in existence. It's the contents of the
source code file at the time that it was translated that matters. The
last phase in which those contents matter is phase 1, and the standard
requires that an implementation shall behave as if the phases were
handled seperately.

> Consider the case of a translated C program whose source code no
> longer exists. What does the C standard guarantee about the behaviour
> of this program?

It guarantees that the program operates exactly the same way it would if
the source code still existed; it does this by failing to specify that
the source code must still exist after having once been translated; or,
for that matter, at any point after translation phase 1.

James Kuyper Jr.

unread,
Feb 8, 2002, 8:40:34 PM2/8/02
to
Dann Corbit wrote:
>
> "Tak-Shing Chan" <es...@city.ac.uk> wrote in message
> news:Pine.GSO.4.21.0202081839030.1092-100000@exeter...
> > On 8 Feb 2002, Dan Pop wrote:
> >
> > > In <Pine.GSO.4.21.0202081116140.10757-100000@exeter> Tak-Shing Chan
> <es...@city.ac.uk> writes:
...

> > >>so you cannot say ``undefined by omission''.
> > >
> > > Of course you can: no source code, no definition of behaviour.
> >
> > Nonsense. Go and learn the differences between a source
> > file and a C program (5p1; 5.1.1.1p1).
>
> Where you see the words "source file" read "translation unit". I think it
> goes without saying that a translation unit is a human-readable entity. A

No, not only is that not obvious, it's also pretty unlikely.
Pre-processing translation units don't come into existence until
translation phases 1-3 have completed. Actual Translation units don't
come into existence until pre-processing is completed. By that point,
I'd expect the translation unit to be stored in whatever internal format
is used by the compiler, and it's rather unlikely that this format is
human-readable. The content of a translation unit is necessarily
equivalent to a single long string of basic source characters, and as
such it would be human readable. However, IMO it's pretty unlikely to be
stored in that form.

> collection of translation units makes up a C program. These translation
> units may also reference C language headers which may or may not be "source
> files" as well [they could be completely internal to the compiler in the
> case of system headers].

No, by the time that it constitutes a translation unit, all such
references have been resolved and removed.

> If you are arguing that object files are portable C and always present well
> defined behavior then I will say this:

Don't worry, no one's made any such suggestion, so you don't have to
argue against it. Now, it is the case that an object file created with a
given implementation of C will have well-defined behavior when linked by
the same implementation to other such object files, if the source code
that went into the creation of all those files defined a program with
well-defined behavior. That's true even if those files no longer exist,
and even if they were never all in existence at the same time. But
that's a very different claim from the straw man you're attacking.

> five year old object file will probably work. A ten minute old object file
> is almost surely going to work. The same thing is not true of a conforming
> C file. A conforming C file can be used at any time and does not degrade,
> unless it uses features that become obsolete (at which time it is no longer
> conforming).

Right - object files cease being useable when they are no longer
compatible with the current version of the implementation used to link
them together. Source code files cease being useable when they are no
longer compatible with the current version of the language standard.

> So, folks on news:comp.std.c -- I would like an interpretation. Does the C
> Standard officially bless object files as conforming inputs to a C program?

No - the standard says nothing about the use of object files as the
inputs to any program other than the linker, and the linker is not
necessarily a C program.

However, the standard does bless them as intermediate files to be used
by the implementation to store the encoded meaning of a source code file
after it's been translated, until such time as it is linked.

> Surely it must do so in the special case of the C compiler's library itself.
> But what about the case of some arbitrary user object files or object
> libraries obtained from 3rd parties?

Third party software is in the same category as user code, with respect
to the C standard. Whether or not a program that is created by linking
together one or more object files has defined behavior, depends upon the
source code that was used to create those object files (whether or not
that source code still exists at link time).

Dann Corbit

unread,
Feb 8, 2002, 8:29:20 PM2/8/02
to
"Barry Margolin" <bar...@genuity.net> wrote in message
news:9oZ88.74$R16.148240@burlma1-snr2...

> In article <a41do...@enews2.newsguy.com>,
> Dann Corbit <dco...@connx.com> wrote:
> >That is very, very unusal. Look at most other systems. E.g. OpenVMS (20
> >years ago would be VMS) used to run on VAX CISC chips and now runs on
Alpha
> >RISC chps. 20 years ago, MS DOS was just born, and ran on 8 bit 8088
chips.
> >In other words, very little objects that are 20 years old will run. 10
year
> >old stuff has a decent chance of running (but not great)
>
> I think you'll find that many programs written for MS-DOS 20 years ago
will
> still run on Windows. The chip manufacturers also tend to be backward
> compatible -- the Pentium instruction set is a superset of the 8086
> instruction set.

Can you link an object file emitted by Microsoft C or Lotus C or Manx C or
Aztec C with your current compiler? That's the question at hand -- not will
an old binary run. That's a completely different issue.

I suspect a lot fewer apps will run today than you think. A lot of them did
things like writing directly to the video frame buffer. That's a no-no
under NT.

> I'm still running some programs on my Apple iBook that were written for
> Macintosh 10 years ago. Apple went so far as to put 68000 emulation into
> their Power Macintosh series of systems to ensure backward compatibility.
>
> >Does the standard say that the implementation must define the behavior as
> >you claim?
> >
> >Where? Chapter and verse?
>
> The standard says that separate compilation is possible. What else could
> that mean other than that you can link the resulting object files
together?

I guess it means that a C interpreter is not allowed by the standard (one of
my other questions only in comp.lang.c).

The standard is wrong. Old objects won't link [except by accident]. Maybe
it says that they can. But it's wrong.

Things like void main() and i=i++ are not nearly so traumatic as attempting
to link a 20 year old object. I think the standard is full of crap, or it's
another "The emperor looks great in those new clothes!"

If the standard codifies something that is clearly impossible, then the
standard is broken.

James Kuyper Jr.

unread,
Feb 8, 2002, 11:20:17 PM2/8/02
to
Dann Corbit wrote:
>
> "Barry Margolin" <bar...@genuity.net> wrote in message
> news:9oZ88.74$R16.148240@burlma1-snr2...
...

> > The standard says that separate compilation is possible. What else could
> > that mean other than that you can link the resulting object files
> together?
...

> The standard is wrong. Old objects won't link [except by accident]. Maybe
> it says that they can. But it's wrong.

Don't worry - that's not what the standard says. It says absolutely
nothing about linking together objects compiled using different
implementations of C. Seperate compilation, and compilation by seperate
implementations of C, are two entirely different issues.

Dik T. Winter

unread,
Feb 9, 2002, 9:00:17 PM2/9/02
to
In article <3C6472B3...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:
> > ... Therefore, in the
> > absence of source code, the standard can't define anything.
>
> In the complete absence of source code, yes. However, the removal of the
> source code after translation phase 1 has completed for each translation
> unit, is something quite different from the complete absence of source
> code.

But that is only the case if you stay on the same system with the same
compiler. So when the source code is absent the program is not portable,
regardless what the original source did. And if you try to port it the
result is really undefined behaviour.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

Dik T. Winter

unread,
Feb 9, 2002, 9:05:18 PM2/9/02
to
In article <3C64784F...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:
> However, the
> behavior of the translated code remains just as well defined as it was
> when the source code was still in existence. It's the contents of the
> source code file at the time that it was translated that matters.

This is false. The object code is tied to a specific compilation system,
so the behaviour is defined only within that compilation system, provided
of course that the original did not have undefined behaviour. So the
translated code is *not* just as well defined as the original source
code.

James Kuyper Jr.

unread,
Feb 9, 2002, 9:10:59 PM2/9/02
to
"Dik T. Winter" wrote:
>
> In article <3C6472B3...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:
> > > ... Therefore, in the
> > > absence of source code, the standard can't define anything.
> >
> > In the complete absence of source code, yes. However, the removal of the
> > source code after translation phase 1 has completed for each translation
> > unit, is something quite different from the complete absence of source
> > code.
>
> But that is only the case if you stay on the same system with the same
> compiler. So when the source code is absent the program is not portable,
> regardless what the original source did. And if you try to port it the
> result is really undefined behaviour.

Agreed - as I've said repeatedly, the standard only defines what happens
if the entire program is translated and executed by a single
implementation of C. However, within that restriction, seperate
compilation does not, in itself, allow undefined behavior.

Dik T. Winter

unread,
Feb 9, 2002, 9:12:21 PM2/9/02
to
In article <3C647EFA...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:
> Right - object files cease being useable when they are no longer
> compatible with the current version of the implementation used to link
> them together. Source code files cease being useable when they are no
> longer compatible with the current version of the language standard.

Object files are not useable right at the moment they are created when
moved to a different system. Source code has a longer lifetime.

> Third party software is in the same category as user code, with respect
> to the C standard. Whether or not a program that is created by linking
> together one or more object files has defined behavior, depends upon the
> source code that was used to create those object files (whether or not
> that source code still exists at link time).

Nope, it also depends on whether the same implementation is used. If
different implementations are used linking may or may not fail, if it
does not fail, execution may or may not fail. The standard tells us
nothing about that, so in my opinion this is undefined behaviour.

Joe Wright

unread,
Feb 9, 2002, 11:39:43 PM2/9/02
to
Any behavior for which 'this International Standard' imposes no
requirements is undefined behavior. What's so hard about that?
--
Joe Wright mailto:joeww...@earthlink.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---

James Kuyper Jr.

unread,
Feb 10, 2002, 8:12:14 AM2/10/02
to
"Dik T. Winter" wrote:
>
> In article <3C64784F...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:
> > However, the
> > behavior of the translated code remains just as well defined as it was
> > when the source code was still in existence. It's the contents of the
> > source code file at the time that it was translated that matters.
>
> This is false. The object code is tied to a specific compilation system,
> so the behaviour is defined only within that compilation system, provided
> of course that the original did not have undefined behaviour. So the
> translated code is *not* just as well defined as the original source
> code.

It is true that the object files can produce behavior that is not
defined by the C standard, if linked to files produced by a different
implementation of C, or by a linker that was incompatible with the
compiler that translated them (the behavior might, however, be defined
by a standard describing the linker). However, that is not something
that has anything to do with the presence or absence of the source code.
If the object files are used properly, the resulting program has defined
behavior, whether or not the source files were deleted between
compilation and linking. If the object files are used improperly, the
resulting program has undefined behavior, whether or not the source
files were deleted between compilation and linking. The erasure is
irrelevant to whether or not the behavior is defined.

The erasure does cause practical problems, in that you can't re-compile
the program when you have a change in compilers. However, that's a very
different issue from whether or not the behavior of a correctly linked
program is defined.

James Kuyper Jr.

unread,
Feb 10, 2002, 8:51:25 AM2/10/02
to
Joe Wright wrote:
>
> Any behavior for which 'this International Standard' imposes no
> requirements is undefined behavior. What's so hard about that?

Nothing. Except for the fact that you have to show that it applies.
Silence by the standard on a given issue is not enough to make the
behavior undefined. The key phrase is "no requirements". If no
requirements apply, then silence by the standard on a given issue means
that the behavior is undefined. However, if at least one requirement
does apply, silence on an issue means that the behavior is defined, in
the absence of any feature that has explicitly undefined behavior. For
instance, the standard does not define the behavior of an implementation
when someone drinks coffee while waiting for a program to compile.
However, that doesn't mean that the behavior of the code is undefined,
if you drink coffee. The standard imposes requirements on the
implementation, and the fact that it doesn't mention coffee does not
revoke those requirements.

For the specific case under discussion:
The standard requires that "A program that is correct in all other
aspects, operating on correct data, containing
unspecified behavior shall be a correct program and act in accordance
with 5.1.2.3.". (This is the same clause I'd cite in the coffee case).
The standard requires that "Implementations shall behave as if these
separate phases occur, ...", including phase 1, which is where the
source code file is read. Therefore, for a program which is correct in
all other aspects, whose source code was available when the standard
says it was needed, during translation phase 1, the standard does
imposes requirements on an implementation. Therefore, you can't use the
"no requirements" clause to use silence as an excuse for undefined
behavior. You need to find an explicit statement in the standard that
makes the behavior is undefined; there aren't any.

Now, it would be perfectly legal for an implementation to say that
translation phase 1 is not complete until just before the program starts
executing. However, any implementation which supports a compile phase
that is seperable from the link phase is implicitly proclaiming that
translation phases 1-7 are complete after compilation.

James Kuyper Jr.

unread,
Feb 10, 2002, 8:56:34 AM2/10/02
to
"Dik T. Winter" wrote:
>
> In article <3C647EFA...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:
> > Right - object files cease being useable when they are no longer
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

> > compatible with the current version of the implementation used to link
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

> > them together. Source code files cease being useable when they are no
> > longer compatible with the current version of the language standard.
>
> Object files are not useable right at the moment they are created when
> moved to a different system. Source code has a longer lifetime.

Exactly as I said; when moved to a different system, they may no longer
be compatible. Source code does have a longer lifetime. However, all I'm
saying is that erasing the source code does not make the behavior
undefined. Changing the system makes the behavior of the object files
undefined, and if the source code has been erased, you won't be able to
create new ones, but the erasure itself does not make the behavior
undefined.

> > Third party software is in the same category as user code, with respect
> > to the C standard. Whether or not a program that is created by linking
> > together one or more object files has defined behavior, depends upon the
> > source code that was used to create those object files (whether or not
> > that source code still exists at link time).
>
> Nope, it also depends on whether the same implementation is used. If

Why "Nope" when you're agreeing with me? That's precisely what I said in
the earlier paragraph.

Dan Pop

unread,
Feb 11, 2002, 4:05:53 AM2/11/02
to
In <Pine.GSO.4.21.0202081844340.1092-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:

>On 8 Feb 2002, Dan Pop wrote:
>
>> In <Pine.GSO.4.21.0202081303100.15560-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
>>> In that case, the behaviour of the complete program is
>>>defined by the rest of the Standard (5.1.1.1p1).
>>
>> Please elaborate. I can't see anything in the standard defining the
>> behaviour of a piece of translated code whose source is no longer
>> available. As far as I can see, the standard deals exclusively in terms
>> of source code, no matter how it is translated. Therefore, in the
>> absence of source code, the standard can't define anything.
>
> Source code is completely irrelevant. The Standard deals
>exclusively in terms of a C program (an abstract entity), not in
>terms of physical source files.

Where have I used the word "file" in my statements above?

But let's have a look at the standard:

5. Environment

[#1] An implementation translates C source files and
executes C programs in two data-processing-system
environments, which will be called the translation
environment and the execution environment in this
International Standard.
...
5.1.1.1 Program structure

[#1] A C program need not all be translated at the same
time. The text of the program is kept in units called
source files, (or preprocessing files) in this International
Standard. A source file together with all the headers and
source files included via the preprocessing directive
#include is known as a preprocessing translation unit.

So, next you're going to tell us that translation units are irrelevant
too :-)

>The mechanism by which C
>programs are transformed for use by a data-processing system is
>outside of the Standard's scope (1p2).

I don't remeber ever invoking "the mechanism by which C programs..." in
this thread, so I fail to see the relevance of this quote.

Dan Pop

unread,
Feb 11, 2002, 4:16:27 AM2/11/02
to
In <3C6472B3...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:

>Dan Pop wrote:
>...
>> available. As far as I can see, the standard deals exclusively in terms
>> of source code, no matter how it is translated. ...
>
>Yes, but source code is only needed during translation phase one, and is
>no longer relevant for any given translation unit once that phase has
>completed.

It is needed any time you need a definition of its behaviour, because the
C standard doesn't define anything in the absence of the source code.

>> ... Therefore, in the
>> absence of source code, the standard can't define anything.
>
>In the complete absence of source code, yes. However, the removal of the
>source code after translation phase 1 has completed for each translation
>unit, is something quite different from the complete absence of source
>code.

It's not different at all, if you need to know how the standard defines
the program's behaviour. If I give you an executable binary and tell you
that it was obtained by translating a strictly conforming C program, how
can you get the definition of its behaviour from the standard? If the
program doesn't behave the way I told you it will, how can you tell if
this is due to a bug in the program or to a non-conforming implementation?

Dan Pop

unread,
Feb 11, 2002, 4:30:43 AM2/11/02
to
In <3C64784F...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:

>Dan Pop wrote:
>
>> In <3C63CD50...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:
>...
>
>>> times when it needed to be available. The fact that it wasn't all
>>> available at the same time is irrelevant. If you believe otherwise,
>>> please cite the text that says so.
>>
>> I have already done it, upthread. If you don't have access to the
>
>I didn't notice any citation that appeared to be relevant to that claim.
>Could you at least give the section number?

This International Standard specifies the form and


establishes the interpretation of programs expressed in the
programming language C.

>> sources NOW, the standard does not define the behaviour of your


>> program, because there is no way to tell what the parts without source
>> code are doing.
>
>If an implementation supports seperate compilation, it must store the
>translated translation unit in some fashion. Whatever medium it chooses
>for that purpose (object files, possibly grouped together into a
>library, are the only medium I've ever heard of) must contain all of the
>information needed to link the program together and execute it; the
>source code no longer needs to exist at that time.

I didn't argue that it needs to exist after translation phase 4. My point
was that if it doesn't exist, the standard can no longer define its
behaviour, because it only deals with source code constructs. And if the
standard doesn't define the program's behaviour, it's undefined, as far
as the standard is concerned.

>> Consider the case of a translated C program whose source code no
>> longer exists. What does the C standard guarantee about the behaviour
>> of this program?
>
>It guarantees that the program operates exactly the same way it would if
>the source code still existed;

But this is NOT a definition of behaviour. The behaviour is the same as
when the source code existed, but it is no longer defined by the standard.

>it does this by failing to specify that
>the source code must still exist after having once been translated; or,
>for that matter, at any point after translation phase 1.

Make that translation phase 4, because this is where #include directives
are processed.

Tak-Shing Chan

unread,
Feb 11, 2002, 6:56:51 AM2/11/02
to
On 11 Feb 2002, Dan Pop wrote:

> In <Pine.GSO.4.21.0202081844340.1092-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
>> Source code is completely irrelevant. The Standard deals
>>exclusively in terms of a C program (an abstract entity), not in
>>terms of physical source files.

^^^^^^^^
> [Quote snipped, 5p1 and 5.1.1.1p1 w.r.t. ``source files'']


> So, next you're going to tell us that translation units are irrelevant
> too :-)

Nice straw-man. Which part of ``physical'' do you not
understand? Whether the physical files exist or not is none of
the Standard's business (1). C source files and C programs
(5.1.1.1) are abstract entities, not physical. Physical source
files belong to the scope of implementations. The Standard do
not know and do not care about ``rm -rf *'' during any
translation phases (1; 5.2.4.1). For a hypothetical mind-reading
implementation, physical source files do not even need to exist.

>>The mechanism by which C
>>programs are transformed for use by a data-processing system is
>>outside of the Standard's scope (1p2).
>
> I don't remeber ever invoking "the mechanism by which C programs..." in
> this thread, so I fail to see the relevance of this quote.

The mechanism could include undeletion of physical files.

The main argument in this thread amounts to appealing to
ignorance: ``if *I* have not seen its source code, then it is
undefined behaviour''. Counterexamples abound.

Tak-Shing

James Kuyper Jr.

unread,
Feb 11, 2002, 7:01:17 AM2/11/02
to
Dan Pop wrote:
>
> In <3C64784F...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:
...

> This International Standard specifies the form and
> establishes the interpretation of programs expressed in the
> programming language C.

Which says nothing about ceasing to define their behavior just because
they've been erased. If they were erased before translation, then
there's an obvious problem with another section of the standard.
However, erasure after translation doesn't remove the fact that they
were "programs expressed in the programming language C", at the only
point in time when they needed to be.

...


> I didn't argue that it needs to exist after translation phase 4. My point

I'm sorry; you're right - it's phase 4, not phase 1, that matters.

> was that if it doesn't exist, the standard can no longer define its
> behaviour, because it only deals with source code constructs. And if the
> standard doesn't define the program's behaviour, it's undefined, as far
> as the standard is concerned.

If the code never existed, then I'd agree. But if the code ever existed,
it's behavior (if linked by the same implementation that it was compiled
by) continues to be defined by the contents of the code as it existed,
when it existed. It doesn't matter whether it still exists.

> >> Consider the case of a translated C program whose source code no
> >> longer exists. What does the C standard guarantee about the behaviour
> >> of this program?
> >
> >It guarantees that the program operates exactly the same way it would if
> >the source code still existed;
>
> But this is NOT a definition of behaviour. The behaviour is the same as
> when the source code existed, but it is no longer defined by the standard.

How does the behavior cease to be defined by the original source code,
just because the source code no longer exists? If the source code said a
= b+c, the standard continues to require that the translated source
code, when linked and executed, must add b to c, and put the result in
a. How does it matter whether the code has been erased?

Of course, if all copies of the code have been erased, there's no way to
verify whether or not the behavior is as defined by the standard.
However, the inability to verify that something is as defined is very
different from it being undefined.

James Kuyper Jr.

unread,
Feb 11, 2002, 7:16:44 AM2/11/02
to
Dan Pop wrote:
>
> In <3C6472B3...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:
...

> It is needed any time you need a definition of its behaviour, because the
> C standard doesn't define anything in the absence of the source code.

True. And the only time that you need to define the behavior which the
program is supposed to have, is at the point where you tell the
implementation what the code is; i.e. during translation. Having defined
the behavior by providing the code at that point, it continues to be
defined even if the code is erased. It doesn't "need definition" any
longer, it already has one.

By the same logic, a soldier could cease following a verbal order, the
minute his commanding officer ceased repeating it out loud. After all,
what he's supposed to do is no longer defined, since the order is no
longer in existence. You can get executed for following that logic in
the army, and I'd advocate a similar attitude toward any compiler that
tried to get away with using the same logic with respect to my code and
the C standard.

> >> ... Therefore, in the
> >> absence of source code, the standard can't define anything.
> >
> >In the complete absence of source code, yes. However, the removal of the
> >source code after translation phase 1 has completed for each translation
> >unit, is something quite different from the complete absence of source
> >code.
>
> It's not different at all, if you need to know how the standard defines

Well, yes, if you need to know it, and no longer remember. That's not
the same as whether or not the behavior is defined.

> the program's behaviour. If I give you an executable binary and tell you
> that it was obtained by translating a strictly conforming C program, how
> can you get the definition of its behaviour from the standard? If the

I can't. That doesn't mean it isn't defined, it just means I can't tell
you what that defined behavior is. The defined behavior of that binary
is just another one of the enormous number of things in this world I
don't know, and can't find out. That doesn't mean that any of those
things don't exist. I don't know what color your hair is (or even if you
have any). Does that mean that your hair is colorless, or that you are
bald?

Dan Pop

unread,
Feb 11, 2002, 8:05:50 AM2/11/02
to
In <Pine.GSO.4.21.0202111030550.18403-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:

>On 11 Feb 2002, Dan Pop wrote:
>
>> In <Pine.GSO.4.21.0202081844340.1092-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
>>> Source code is completely irrelevant. The Standard deals
>>>exclusively in terms of a C program (an abstract entity), not in
>>>terms of physical source files.
> ^^^^^^^^
>> [Quote snipped, 5p1 and 5.1.1.1p1 w.r.t. ``source files'']
>> So, next you're going to tell us that translation units are irrelevant
>> too :-)
>
> Nice straw-man. Which part of ``physical'' do you not
>understand? Whether the physical files exist or not is none of
>the Standard's business (1). C source files and C programs
>(5.1.1.1) are abstract entities, not physical. Physical source
>files belong to the scope of implementations.

And their removal belongs to the same scope. So, what is your point?

>The Standard do
>not know and do not care about ``rm -rf *'' during any
>translation phases (1; 5.2.4.1). For a hypothetical mind-reading
>implementation, physical source files do not even need to exist.

For the same implementation, forgetting the source code is the equivalent
of removing the physical source files. So, what exactly is your point?

Again, nobody but you talked about *physical* source files. You seem to
generate a strawman per post, lately.

>>>The mechanism by which C
>>>programs are transformed for use by a data-processing system is
>>>outside of the Standard's scope (1p2).
>>
>> I don't remeber ever invoking "the mechanism by which C programs..." in
>> this thread, so I fail to see the relevance of this quote.
>
> The mechanism could include undeletion of physical files.

So what? Both mechanism and physical files are irrelevant to the
discussion. The source code could be delivered together with the
library, on paper or microfiche.

> The main argument in this thread amounts to appealing to
>ignorance: ``if *I* have not seen its source code, then it is
>undefined behaviour''. Counterexamples abound.

If the source code is not available, the standard cannot specify its
behaviour.

Dan Pop

unread,
Feb 11, 2002, 8:09:03 AM2/11/02
to
In <3C67B39C...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:

>Dan Pop wrote:
>>
>> But this is NOT a definition of behaviour. The behaviour is the same as
>> when the source code existed, but it is no longer defined by the standard.
>
>How does the behavior cease to be defined by the original source code,
>just because the source code no longer exists?

How can a non-existing entity define anything at all?

Richard Bos

unread,
Feb 11, 2002, 8:19:42 AM2/11/02
to

In general, I think you're correct. Note, however, that this scenario
demands that we _know_ the original code was suitably conforming. The
linker has no memory; it cannot know whether the object file it is
linking does or does not invoke UB. It is the user who must make sure
that the code is indeed defined code.
In the case of a single user who compiles several translation units,
then deletes the source, then links them, that is easily guaranteed. If,
however, we have an object file, and we are told that it _could_ be
conforming, defined code, IMO linking it still defines UB, never mind
whether it originally was defined code or not. Why? Simply because we do
not _know_ that it was defined. We, the users, _don't_, and the
implementation _can't_.

In the post that sparked this thread, the latter was the case.
Someone(1) called clrscr(). Someone(2) else claimed that calling
clrscr() without providing a definition invokes UB. Someone(3) protested
that there could have been defined code for clrscr() elsewhere, and
therefore someone(2) cannot claim that calling it _does_ invoke UB, only
that it might.
IYAM, someone(2) is correct, as long as we have not seen defined code
for the function in question, or _know_, not guess, that it _is_, not
may be, well defined. BIANALL.
And note, this is IMO true only in this case, where we just do not know
anything about the called function. If we just compiled it and call it
while still knowing that it is defined, your argument holds.

Richard

Tak-Shing Chan

unread,
Feb 11, 2002, 10:41:46 AM2/11/02
to
On 11 Feb 2002, Dan Pop wrote:

> In <Pine.GSO.4.21.0202111030550.18403-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
>> Nice straw-man. Which part of ``physical'' do you not
>>understand? Whether the physical files exist or not is none of
>>the Standard's business (1). C source files and C programs
>>(5.1.1.1) are abstract entities, not physical. Physical source
>>files belong to the scope of implementations.
>
> And their removal belongs to the same scope. So, what is your point?

So we are finally in agreement regarding the inapplicability
of C99 to physical files. The only disagreement here is about
the effects of removing C source files before TP8.

>>The Standard do
>>not know and do not care about ``rm -rf *'' during any
>>translation phases (1; 5.2.4.1). For a hypothetical mind-reading
>>implementation, physical source files do not even need to exist.
>
> For the same implementation, forgetting the source code is the equivalent
> of removing the physical source files. So, what exactly is your point?

As I have pointed out before (7 Feb 2002), C source files
are no longer needed at TP8 where the libraries are linked.

> Again, nobody but you talked about *physical* source files. You seem to
> generate a strawman per post, lately.

It is you, not me. You stated ``if I am not able to /see/
it as code, my translator is not able to see it as code either''
(6 Feb 2002). Your ability to see it implies the physical
manifestation of source files.

>> The mechanism could include undeletion of physical files.
>
> So what? Both mechanism and physical files are irrelevant to the
> discussion. The source code could be delivered together with the
> library, on paper or microfiche.

You have missed the main point: it does not have to be
delivered to *you*. It just need to be delivered to the
translator that produces the library.

>> The main argument in this thread amounts to appealing to
>>ignorance: ``if *I* have not seen its source code, then it is
>>undefined behaviour''. Counterexamples abound.
>
> If the source code is not available, the standard cannot specify its
> behaviour.

It has been said repeatedly (in the library example) that
the source code is available to the translator. The C Standard
applies to what the translator sees, not what you can see.

Tak-Shing

Tim Woodall

unread,
Feb 11, 2002, 10:50:06 AM2/11/02
to
On Mon, 11 Feb 2002 13:19:42 GMT,
Richard Bos <in...@hoekstra-uitgeverij.nl> wrote:
>
> In general, I think you're correct. Note, however, that this scenario
> demands that we _know_ the original code was suitably conforming. The
> linker has no memory; it cannot know whether the object file it is
> linking does or does not invoke UB. It is the user who must make sure
> that the code is indeed defined code.

Is this strictly true?

Were I to write a function:
int invoke_undefined_behaviour(int x) { return x++ + x; }
and compile it into a library.

I then delete the source and supply you with the library.
(I also tell you that the function returns 2*x+1)

If you call invoke_undefined_behaviour as part of an otherwise
well defined C program is the resultant program undefined?

Obviously we cannot say what it might do.

But if someone else reverse engineered the function and said
int invoke_undefined_behaviour(int x) { return x+x+1; } generates
identical assembly and an identical library and so provided you
with the "source" to the library. Does your code then become
defined a) If you do not recompile my library, b) if you do
recompile it with the well behaved code?

Perhaps followups should go to comp.lang.philosophy (if it
exists :-)

Tim.

--
God said, "div D = rho, div B = 0, curl E = - @B/@t, curl H = J + @D/@t,"
and there was light.

http://tjw.hn.org/ http://www.locofungus.btinternet.co.uk/

Dik T. Winter

unread,
Feb 11, 2002, 11:20:17 AM2/11/02
to
In article <Pine.GSO.4.21.0202111442310.1315-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
> On 11 Feb 2002, Dan Pop wrote:
...

> > So what? Both mechanism and physical files are irrelevant to the
> > discussion. The source code could be delivered together with the
> > library, on paper or microfiche.
>
> You have missed the main point: it does not have to be
> delivered to *you*. It just need to be delivered to the
> translator that produces the library.

You have missed the main point: it could be delivered to the translator
together with the libary, on paper or microfiche.

Richard Bos

unread,
Feb 11, 2002, 11:49:59 AM2/11/02
to
t...@pauli.locofungus.org (Tim Woodall) wrote:

> On Mon, 11 Feb 2002 13:19:42 GMT,
> Richard Bos <in...@hoekstra-uitgeverij.nl> wrote:
> >
> > In general, I think you're correct. Note, however, that this scenario
> > demands that we _know_ the original code was suitably conforming. The
> > linker has no memory; it cannot know whether the object file it is
> > linking does or does not invoke UB. It is the user who must make sure
> > that the code is indeed defined code.
>
> Is this strictly true?
>
> Were I to write a function:
> int invoke_undefined_behaviour(int x) { return x++ + x; }
> and compile it into a library.
>
> I then delete the source and supply you with the library.
> (I also tell you that the function returns 2*x+1)
>
> If you call invoke_undefined_behaviour as part of an otherwise
> well defined C program is the resultant program undefined?

Yes, IMO.

In fact, I'd say it is even undefined if I call this function, and it is
not undefined but perfectly defined, _but_ I can no longer ascertain
that it is.

> Obviously we cannot say what it might do.

So, obviously, it is undefined.

Richard

Tak-Shing Chan

unread,
Feb 11, 2002, 12:39:36 PM2/11/02
to
On Mon, 11 Feb 2002, Dik T. Winter wrote:

>> You have missed the main point: it does not have to be
>> delivered to *you*. It just need to be delivered to the
>> translator that produces the library.
>
> You have missed the main point: it could be delivered to the translator
> together with the libary, on paper or microfiche.

I failed to see how this is relevant to my previous posts.
Specifically, I have repeatedly stated the physical format of the
actual source files in which the translator uses (be it paper or
microfiche) is outside of the scope of the Standard (1p2), and
thus your ``point'' is irrelevant to the current discussion.

Tak-Shing

Barry Margolin

unread,
Feb 11, 2002, 2:07:23 PM2/11/02
to
In article <a4825b$qpk$1...@sunnews.cern.ch>, Dan Pop <Dan...@ifh.de> wrote:
>It is needed any time you need a definition of its behaviour, because the
>C standard doesn't define anything in the absence of the source code.

Does it even contain a formal definition of source code? How do you know
if a particular file is "source code"?

The problem with your ultra-pedantic intepretation of the standard is that
it ignores reality. The standard is intended to be read by people with
common sense and who are familiar with the context of computer systems and
programming languages. It doesn't go into detail about the general
operation of these systems, because a) that would be beyond the scope of
the standard, and b) they can vary quite a bit between implementations
(just consider the differences between compilers and interpreters).

It's up to the user to understand how to apply the notions that the
standard refers to, such as separate compilation and libraries, to the
particular computing system they're using. For instance, if Solaris 2.6 is
upward compatible with Solaris 2.5, you know that you should be able to
take a program compiled for 2.5 and run it under 2.6 with the same expected
results. This is not a detail that can reasonably be spelled out in the C
standard.

--
Barry Margolin, bar...@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Barry Margolin

unread,
Feb 11, 2002, 2:15:40 PM2/11/02
to
In article <a48303$r1q$1...@sunnews.cern.ch>, Dan Pop <Dan...@ifh.de> wrote:
>I didn't argue that it needs to exist after translation phase 4. My point
>was that if it doesn't exist, the standard can no longer define its
>behaviour, because it only deals with source code constructs.

But can't we refer to what the source file used to contain? Isn't it
possible to reason about things that don't exist any more?

Dann Corbit

unread,
Feb 11, 2002, 1:57:25 PM2/11/02
to
"Tak-Shing Chan" <es...@city.ac.uk> wrote in message
news:Pine.GSO.4.21.0202111733510.9095-100000@exeter...

The point isn't "What format exactly are these sources in?"

It is (rather) "Are the sources necessary?"
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
"The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm


Tak-Shing Chan

unread,
Feb 11, 2002, 2:51:16 PM2/11/02
to
On Mon, 11 Feb 2002, Dann Corbit wrote:

> The point isn't "What format exactly are these sources in?"
>
> It is (rather) "Are the sources necessary?"

Definitely not in TP8. In fact, Dan Pop goes even further
to assert that source files are not needed after TP4 (``make that
translation phase 4''). So he seems to be contradicting himself.

Tak-Shing

Thomas Stegen

unread,
Feb 11, 2002, 2:59:51 PM2/11/02
to
"Dan Pop" <Dan...@ifh.de> wrote in message
news:a48fpf$5r9$1...@sunnews.cern.ch...

> In <3C67B39C...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net>
writes:
>
> >Dan Pop wrote:
> >>
> >> But this is NOT a definition of behaviour. The behaviour is the same
as
> >> when the source code existed, but it is no longer defined by the
standard.
> >
> >How does the behavior cease to be defined by the original source code,
> >just because the source code no longer exists?
>
> How can a non-existing entity define anything at all?
>

I wouldn't use a computer with so many programs
invoking UB. Many of the programs I am using was
probably written in C, I haven't seen the source code
and the programmers probably hadn't seen a lot of the
code for the libraries, and who knows some of that
source code might not exist any more.

Also how can you be so sure that a compiled program
really was compiled from the source it was supplied
with? You can't. Hence, by your argument any program
which you didn't compile yourself invokes UB.


--
Thomas.

Approaching singularity.


Dann Corbit

unread,
Feb 11, 2002, 3:30:58 PM2/11/02
to
"Thomas Stegen" <tho_s...@hotmail.com> wrote in message
news:a49830$nsp$1...@dennis.cc.strath.ac.uk...


I think the argument would be (rather) that any program which uses objects
or libraries containing functions without source code and which are not
supplied by the implementation's standard library invokes undefined
behavior.

I think that is a true statement.

If the behavior is defined, what must it be? What does clrscr() or utime()
do?

Behavior can be defined by something outside of the standard.
Implementations can add extensions or we can use POSIX stuff or GKS or PHIGS
and know how these things are going to behave outside of the C standard
because they are documented elsewhere.

As far as the C language is concerned, I think the behavior is undefined.

Suppose that I link against a Winsock library and it turns out to be OS/2
instead of Win32. Demons come flying out of my nose, even though I have
used the API's correctly.

Here is what we can know:
1. If the objects and libraries in use were composed completely from
ANSI/ISO compliant code (both at the time of compiling and also the code
would still be or have been compliant at the time of linking -- standards
change)
2. If the objects are compatible with the current compiler[*]
3. If the objects are compatible with the current operating system[*]
4. If the compiler is operating in ANSI/ISO mode both at the time earlier
compile and now
5. If the compiler itself is not changed and/or is compatible with the
version that compiled the objects
6. If the linker and object librarian system are also compatible with all
objects

{If any of the above requirements can be left out, which is it? I imagine
that there are several more as well, that did not occur to me.} Then the
behavior can be defined. However, lacking source code, how will we verify
it? It now depends upon the memory of the programmer. Sounds like a pretty
loose definition of compliant and defined behavior to me. One thing for
sure -- lacking source code it is clearly impossible to prove compliance.
Unless we have somehow figured out whether or not the Turing machine will
halt.

[*] Whatever that means

Barry Margolin

unread,
Feb 11, 2002, 5:31:21 PM2/11/02
to
In article <a499e...@enews4.newsguy.com>,

Dann Corbit <dco...@connx.com> wrote:
>{If any of the above requirements can be left out, which is it? I imagine
>that there are several more as well, that did not occur to me.} Then the
>behavior can be defined. However, lacking source code, how will we verify
>it?

Why do you need to verify it? Some things have to be accepted as given
unless you have evidence otherwise.

If the vendor lies to you about the nature of the library, then things
won't work as expected. This is because you were misinformed, not because
your program doesn't follow the standard.

Suppose you use the fopen() function, but the implementation has a bug in
the code for this. Your program will still misbehave, even though it's
totally conforming.

Either way, the vendor misinformed you about what their library: in the
first case it was about whether the library is compatible with your
implementation, in the second it was about whether they correctly implement
the ANSI/ISO standard library.

Dann Corbit

unread,
Feb 11, 2002, 6:36:48 PM2/11/02
to
"Barry Margolin" <bar...@genuity.net> wrote in message
news:ZCX98.27$g01.152539@burlma1-snr2...

> In article <a499e...@enews4.newsguy.com>,
> Dann Corbit <dco...@connx.com> wrote:
> >{If any of the above requirements can be left out, which is it? I
imagine
> >that there are several more as well, that did not occur to me.} Then the
> >behavior can be defined. However, lacking source code, how will we
verify
> >it?

Accept what? I have a object module with a function called clrscr() in it.
Maybe it's from a vendor. Maybe I compiled it myself. Maybe I downloaded
it from Simtel. Maybe I can't even remember. The question is: "What does
it do?" The answer is...
Not defined by the C language unless I have the source code.

> Why do you need to verify it? Some things have to be accepted as given
> unless you have evidence otherwise.

Unless it is documented, it is silly to accept it. If it is documented,
then:
1. If it is a vendor product, then the vendor must accept some risk that it
will work as documented
2. If it is not a vendor product, then the tool user incurs all risk.

In either case, the C language standard says nothing about what it does or
might do.

> If the vendor lies to you about the nature of the library, then things
> won't work as expected. This is because you were misinformed, not because
> your program doesn't follow the standard.

The standard I am relying on (in this case) is the extension offered by the
vendor. It is not something endorsed by the C language. Rather, it is
something that I hope will work, and if it fails, I will have to plead with
the vendor to fix it or take them to court or whatever.

> Suppose you use the fopen() function, but the implementation has a bug in
> the code for this. Your program will still misbehave, even though it's
> totally conforming.

If they claim to have an ANSI compiler then I can use that in a court of law
to defend myself. If I am using the fraboozle() function, then I am at
considerably more risk (IMO).

> Either way, the vendor misinformed you about what their library: in the
> first case it was about whether the library is compatible with your
> implementation, in the second it was about whether they correctly
implement
> the ANSI/ISO standard library.

And one is covered by the ANSI/ISO standard and the other is not.
Personally, I think it is absurd to assume that systems outside of the
standard are conforming. From the point that we start using vendor
extensions on forward, we are operating on trust.

Did the vendor use assembly language extensions? Did the vendor have i=i++
in his code? There is absolutely no way for me to know. I don't see how
anyone can say that usage of non-standard libraries or objects results in
defined behavior. "Defined by what?" Certainly not by the C Standard. If
(by some miracle) every construct in the library is pure and 100% correct
ANSI C, I will still have no way to verify it.

That does not mean that programs using these sort of things cannot create
correct results. But I believe that we no longer have the ANSI standard as
a protection once we do (at least for any parts of a system that directly
rely upon things not covered by the standard).

Sometimes we will have to use this sort of extension (or inline assembly or
whatever...)
Sometimes these extensions are a very good idea. But I think it is an
illusion to imagine that the behavior of programs that rely upon them are
standardized or somehow compliant and producing ANSI/ISO defined behaviors.
The behaviors we receive are (rather) vendor defined. And so using them is
a function of how much we trust that particular vendor.

James Kuyper Jr.

unread,
Feb 11, 2002, 8:11:43 PM2/11/02
to
Dan Pop wrote:
>
> In <3C67B39C...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:
...

> >How does the behavior cease to be defined by the original source code,
> >just because the source code no longer exists?
>
> How can a non-existing entity define anything at all?

By having been in existence at the time it needed to exist, in order to
define the behavior.

James Kuyper Jr.

unread,
Feb 11, 2002, 8:30:00 PM2/11/02
to
Dann Corbit wrote:
>
> "Thomas Stegen" <tho_s...@hotmail.com> wrote in message
> news:a49830$nsp$1...@dennis.cc.strath.ac.uk...
> > "Dan Pop" <Dan...@ifh.de> wrote in message
> > news:a48fpf$5r9$1...@sunnews.cern.ch...
> > > In <3C67B39C...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net>
> > writes:
...

> If the behavior is defined, what must it be? What does clrscr() or utime()
> do?

Precisely what it's source code said it should do. Whether that source
code still exists determines whether or not you can determine whether
the behavior of that code is defined, but that doesn't change whether or
not the code's behavior is defined.

...


> Suppose that I link against a Winsock library and it turns out to be OS/2
> instead of Win32. Demons come flying out of my nose, even though I have
> used the API's correctly.

Yes - because the compiler that was used to compile that code, and the
linker that was used to link it, do not together constitute a conforming
implementation of C. That is completely independent of whether or not
the source code still exists.

> Here is what we can know:

[Long list of requirements for successful seperate compilation]


> {If any of the above requirements can be left out, which is it? I imagine

None, but they all boil down to one requirement: the code must be
compiled and linked by a compiler and linker that together constitute a
conforming implementation of C (taking into the consideration the
compiler/linker options that were specified). Every single item you
listed will (usually, but not necessarily) create a situation where he
combination is not a conforming implmentation.

...


> that there are several more as well, that did not occur to me.} Then the
> behavior can be defined. However, lacking source code, how will we verify
> it?

Code that has undefined behavior is different from code that can't be
proven to have defined behavior. It's precisely the same distinction as
the one between people who are guilty of murder, and people who can't be
proven innocent of murder. Ideally, the first group is a subset of the
second, but it is not the same as the second group (in either case).

> loose definition of compliant and defined behavior to me. One thing for
> sure -- lacking source code it is clearly impossible to prove compliance.

True. That doesn't mean the code isn't compliant, merely that you can't
find out whether it's compliant.

James Kuyper Jr.

unread,
Feb 11, 2002, 8:51:13 PM2/11/02
to
Richard Bos wrote:
>
> "James Kuyper Jr." <kuy...@wizard.net> wrote:
...

> > In the complete absence of source code, yes. However, the removal of the
> > source code after translation phase 1 has completed for each translation
> > unit, is something quite different from the complete absence of source
> > code.
>
> In general, I think you're correct. Note, however, that this scenario
> demands that we _know_ the original code was suitably conforming. The
> linker has no memory; it cannot know whether the object file it is
> linking does or does not invoke UB. It is the user who must make sure
> that the code is indeed defined code.

You're missing the point of UB. The linker isn't responsible for
checking for UB. It's only responsible for making sure that it produces
the defined behavior, when the behavior is defined. A linker has all the
memory it needs, to achieve this - that memory is called "object files".
The linker doesn't need to know what that behavior is; it's just
responsible for following the instructions placed in those files by the
compiler. It's up to the compiler to put into those files whatever
information the linker needs to produce the behavior defined by the
standard. And if it did do so, the program will produce the defined
behavior, even if the source code that told the compiler what that
behavior should be, has since disappeared.

> In the case of a single user who compiles several translation units,
> then deletes the source, then links them, that is easily guaranteed. If,
> however, we have an object file, and we are told that it _could_ be
> conforming, defined code, IMO linking it still defines UB, never mind
> whether it originally was defined code or not. Why? Simply because we do
> not _know_ that it was defined. We, the users, _don't_, and the
> implementation _can't_.

Just because you don't know what the defined behavior is, doesn't mean
that the behavior isn't defined. Just because you don't know what color
my car is, doesn't mean that my car is colorless.

Dann Corbit

unread,
Feb 11, 2002, 8:32:16 PM2/11/02
to
"James Kuyper Jr." <kuy...@wizard.net> wrote in message
news:3C686CBD...@wizard.net...

This is starting to sound like:
"If a tree falls in a forest with no ear to hear it..."

If I email an object module to you, and claim that it is conformant and
exhibits always defined behavior, and then you link a program with it, is
the behavior of the program defined?

Is the memory of the programmer "This thing has no undefined behavior that I
recall" enough to make the behavior defined?

Must defined behavior be verifiable, or is a memory enough to make it so?
If a memory that a program was well defined is enough, do we even need to
examine source code to determine correctness? Maybe we should all delete
our source code after the apps ship.
;-)

James Kuyper Jr.

unread,
Feb 11, 2002, 9:39:34 PM2/11/02
to
Dann Corbit wrote:
>
> "James Kuyper Jr." <kuy...@wizard.net> wrote in message
> news:3C686CBD...@wizard.net...
> > Dan Pop wrote:
> > >
> > > In <3C67B39C...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net>
> writes:
> > ...
> > > >How does the behavior cease to be defined by the original source code,
> > > >just because the source code no longer exists?
> > >
> > > How can a non-existing entity define anything at all?
> >
> > By having been in existence at the time it needed to exist, in order to
> > define the behavior.
>
> This is starting to sound like:
> "If a tree falls in a forest with no ear to hear it..."

Exactly. The realist claims that the sound exists, whether or not anyone
hears it. I've never seen any point in Bishop Berkeley's take on the
issue. I understand his point, incidentally: all we really know are our
perceptions; it's inherently impossible to know what the causes of our
perceptions are; the best we can do is guess, and require that our
guesses be internally consistent, as well as being consistent with the
perceptions they're intended to explain. However, I don't see any point
in worrying about it; if you can't tell whether you're being fooled by a
Divinely perfect simulation of a non-existent external reality, knowing
that you might be being fooled doesn't do you any good; there's no
useful decisions that can be made based upon that awareness.
If you have no idea what I'm talking about, you might want to read up on
Bishop Berkeley, and what he was talking about when he posed that
question. He makes my worst bouts of pedantry sound practically normal,
by comparison.

> If I email an object module to you, and claim that it is conformant and
> exhibits always defined behavior, and then you link a program with it, is
> the behavior of the program defined?

Only if your claim was correct. What matters is whether or not the
behavior is defined, not whether you know that it's defined, and not
whether or not you can verify that it is defined. If the behavior was
defined when the source code existed, removing the code only removes the
ability to verify it; it doesn't change the fact that it was defined.

If I send you a kitten, and claim that it's father had black hair, does
the truth (or falsity) of my statement depend upon whether or not any
evidence survives to prove it (or disprove it)? I you say "yes", then
your concept of what "truth" means is too incompatible with mine, to
allow for coherent conversation (which would explain a lot about this
thread).

> Is the memory of the programmer "This thing has no undefined behavior that I
> recall" enough to make the behavior defined?

Only if that memory was correct.

> Must defined behavior be verifiable, or is a memory enough to make it so?

No - defined behavior exists, whether or not it is verifiable, just like
just about every other feature of reality. My wife exists (or doesn't
:-), regardless of whether or not you can verify the fact.

> If a memory that a program was well defined is enough, do we even need to
> examine source code to determine correctness? Maybe we should all delete
> our source code after the apps ship.
> ;-)

No, examining source code is precisely what you want to do to determine
whether it's correct. However, it's correct, or not, completely
independent of whether or not anyone ever does verify the fact; in fact,
it's independent of whether or not anyone could verify the fact.

David Hopwood

unread,
Feb 10, 2002, 10:28:51 PM2/10/02
to
-----BEGIN PGP SIGNED MESSAGE-----

Dan Pop wrote:
> "James Kuyper Jr." <kuy...@wizard.net> writes:
> >Dan Pop wrote:
> >>
> >> But this is NOT a definition of behaviour. The behaviour is the same as
> >> when the source code existed, but it is no longer defined by the standard.
> >
> >How does the behavior cease to be defined by the original source code,
> >just because the source code no longer exists?
>
> How can a non-existing entity define anything at all?

Consider a compiler for OtherLanguage that uses C as an intermediate
representation, i.e. it compiles to C (either in a file or in memory),
runs the C compiler, deletes the C source, then links the object file(s)
using a compatible linker.

The C Standard *does* specify the behaviour of the resulting executable
in terms of what C source was produced. Suppose for simplicity that
the compiler is also written in C; in that case to analyse its correctness
(assuming that the C implementation is conformant), you need only:
- its source
- the C Standard
- the specification of OtherLanguage.

You do *not* need any particular C output, so whether and when that
output is deleted is beside the point.

Also note that nothing here depends on the OtherLanguage compiler being
deterministic - it may be possible to show that it is correct without
being able to reconstruct its output in any particular case, by showing
that all possible outputs are correct.

- --
David Hopwood <david....@zetnet.co.uk>

Home page & PGP public key: http://www.users.zetnet.co.uk/hopwood/
RSA 2048-bit; fingerprint 71 8E A6 23 0E D3 4C E5 0F 69 8C D4 FA 66 15 01
Nothing in this message is intended to be legally binding. If I revoke a
public key but refuse to specify why, it is because the private key has been
seized under the Regulation of Investigatory Powers Act; see www.fipr.org/rip


-----BEGIN PGP SIGNATURE-----
Version: 2.6.3i
Charset: noconv

iQEVAwUBPGb9/DkCAxeYt5gVAQF0PQgAjAP9QiUcfwHvWWqjEBwwMri+Zc/HA3HN
WcM+N251iHde4CR5R+lCoAr39YsWQU08fuT1m5nvMLUiPnZw7TeVD3RVmgaLqjIA
O92bAatbxfFot3qKbhVD7FyOSTmq0LPGsdKa713klg0QFVrEWraU2UtbWXBkVY1H
LxBsqYCYluEb2xA6E3/XWUzLudxifRHk/VGIDRNeFXfFWqgBvbROw6f8HE9fsalr
JJZZvNWmgXrSQPbIt/1BETM1xsSW6f5aiXz7ln5wcEU8+0XfiM6B4q7zpdHqVAH8
5as382kJVuh1YmQoBp5mySNQ/Rt4YT5OPXzDRbKyZqTmBL7NDMBZrg==
=EvCX
-----END PGP SIGNATURE-----

Dan Pop

unread,
Feb 12, 2002, 4:06:28 AM2/12/02
to
In <Pine.GSO.4.21.0202111442310.1315-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:

> It has been said repeatedly (in the library example) that
>the source code is available to the translator. The C Standard
>applies to what the translator sees, not what you can see.

Nope, it applies to both. If I don't see what the translator has seen,
I don't have a definition of behaviour from the standard. So, my
program invokes undefined behaviour if it calls one function from that
third party library. If you disagree, please provide a definition of
behaviour for my program, based on the text of the standard.

[#1] undefined behavior
behavior, upon use of a nonportable or erroneous program
^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^
construct, of erroneous data, or of indeterminately valued
^^^^^^^^^
objects, for which this International Standard imposes no
requirements

The underlined part in the definition of undefined behavior applies here,
because calling a third party library function is, by definition,
nonportable (in the context of the standard).

Dan Pop

unread,
Feb 12, 2002, 4:16:53 AM2/12/02
to

I'm not contradicting myself at all. To the translator, the source
*files* are no longer needed after TP4. To the programmer, the source
*code* is needed anytime he has to provide a definition of behaviour for
his program, based exclusively on the text of the standard.

The standard is not written *exclusively* as a specification for
translators, it is also meant to provide a definition of behaviour for
C programs. And its actual wording requires access to the complete
source code (regardless of how it is translated) in order to have the
behaviour defined.

Dan Pop

unread,
Feb 12, 2002, 4:20:31 AM2/12/02
to

But I need the definition NOW, when I'm calling that library function.
Where do I find it, in the C standard?

David Tanguay

unread,
Feb 12, 2002, 6:25:54 AM2/12/02
to
Dan...@ifh.de wrote:
> I'm not contradicting myself at all. To the translator, the source
> *files* are no longer needed after TP4. To the programmer, the source
> *code* is needed anytime he has to provide a definition of behaviour for
> his program, based exclusively on the text of the standard.

Why does a source file ever have to exist? Can't a compiler read lines
from stdin, typed/generated by a user/program? The entire translation
unit would have never existed in its entirety. I.e., a translation unit
is an abstract entity, not necessarily a physical one.
--
David Tanguay d...@Thinkage.ca http://www.thinkage.ca/~dat/
Thinkage, Ltd. Kitchener, Ontario, Canada [43.24N 80.29W]

Tak-Shing Chan

unread,
Feb 12, 2002, 7:25:54 AM2/12/02
to

^^^^^^^^^^^^^


> nonportable (in the context of the standard).

There is no such definition in the context of the Standard.
clrscr() is a portable construct (an identifier followed by
parentheses denotes a function call, and clrscr is a legal
identifier).

Details of the library mechanism, while nonportable, is not
even a /program construct/. Such mechanisms are outside of the
scope of the C Standard (1p2).

Tak-Shing

Tak-Shing Chan

unread,
Feb 12, 2002, 7:41:02 AM2/12/02
to
On 12 Feb 2002, Dan Pop wrote:

> In <Pine.GSO.4.21.0202111924500.13307-100000@exeter> Tak-Shing Chan <es...@city.ac.uk> writes:
>>On Mon, 11 Feb 2002, Dann Corbit wrote:
>>> It is (rather) "Are the sources necessary?"
>> Definitely not in TP8. In fact, Dan Pop goes even further
>>to assert that source files are not needed after TP4 (``make that
>>translation phase 4''). So he seems to be contradicting himself.
>
> I'm not contradicting myself at all. To the translator, the source
> *files* are no longer needed after TP4. To the programmer, the source
> *code* is needed anytime he has to provide a definition of behaviour for

^^^^^^^^^^^^^^^^^^^^^^^^^^^


> his program, based exclusively on the text of the standard.

^^^^^^^^^^^

You have no right to provide a /definition/ of behaviour for
C programs. Only the C Standard has this authority.

> The standard is not written *exclusively* as a specification for
> translators, it is also meant to provide a definition of behaviour for
> C programs. And its actual wording requires access to the complete
> source code (regardless of how it is translated) in order to have the
> behaviour defined.

No. It actual wordings requires /no/ access to the source
code after TP4, as you have said before.

Tak-Shing

James Kuyper Jr.

unread,
Feb 12, 2002, 8:58:35 AM2/12/02
to
Dan Pop wrote:
>
> In <3C686CBD...@wizard.net> "James Kuyper Jr." <kuy...@wizard.net> writes:
>
> >Dan Pop wrote:
...

> >> How can a non-existing entity define anything at all?
> >
> >By having been in existence at the time it needed to exist, in order to
> >define the behavior.
>
> But I need the definition NOW, when I'm calling that library function.
> Where do I find it, in the C standard?

You can't. Just because the behavior's defined, doesn't mean that you
can determine what the defined behavior is. That's a fairly normal
feature of reality. Things that are both true and knowable are actually
fairly rare; it only seems otherwise because most people avoid thinking
about the unknowable truths. That's a problem, and a serious one, but
it's not the same problem as the one you've been describing.

James Kuyper Jr.

unread,
Feb 12, 2002, 9:00:40 AM2/12/02
to
Dan Pop wrote:
...

> I'm not contradicting myself at all. To the translator, the source
> *files* are no longer needed after TP4. To the programmer, the source
> *code* is needed anytime he has to provide a definition of behaviour for
> his program, based exclusively on the text of the standard.

Yes, the programmer needs the text in order to know whether the behavior
is defined, and what that defined behavior is. However, the text is not
needed for the behavior itself to be defined.

James Kuyper Jr.

unread,
Feb 12, 2002, 9:06:30 AM2/12/02
to
Dan Pop wrote:
...

> because calling a third party library function is, by definition,
> nonportable (in the context of the standard).

No, not by definition. The standard doesn't distinguish between third
party code and your code; all of that code together constitutes a single
program. That program can (depending upon how it's written) have
behavior defined by the C standard, if all of it is written in C, and
all of it was translated and linked together by the same implementation
of C. Whether or not you have access to all of that code is irrelevant
to whether or not the behavior is defined. Of course, such access is
helpful in verifying that that it should have defined behavior.

Nils Goesche

unread,
Feb 12, 2002, 12:03:23 PM2/12/02
to

Somehow this reminds me of Fermat's conjecture, sometimes called his
``Last Theorem''. By this logic, it wasn't a conjecture until Andrew
Wiles proved it for all to see, but should have been considered proven
all the time because there once was a proof in Fermat's head :-)

Regards,
--
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9

Dann Corbit

unread,
Feb 12, 2002, 1:42:09 PM2/12/02
to
"David Tanguay" <gravi...@thinkage.ca> wrote in message
news:MPG.16d2c5c58...@nntp.uunet.ca...

> Dan...@ifh.de wrote:
> > I'm not contradicting myself at all. To the translator, the source
> > *files* are no longer needed after TP4. To the programmer, the source
> > *code* is needed anytime he has to provide a definition of behaviour for
> > his program, based exclusively on the text of the standard.
>
> Why does a source file ever have to exist? Can't a compiler read lines
> from stdin, typed/generated by a user/program? The entire translation
> unit would have never existed in its entirety. I.e., a translation unit
> is an abstract entity, not necessarily a physical one.


The file stdin is the file in this case. It's temporal nature is the thing
in question.

I guess there are two camps of interpretation.

Camp 1: It does not matter if you can verify it or not. As long as it
works, it is defined behavior.

Camp 2: If you cannot demonstrate by proof that the behavior is defined
then it is not defined.

I think that the second is logical and the first is illogical. I am not
saying that undefined behavior is not useful. Only that if you can't prove
it, you can't know it. It's only a guess.

Dann Corbit

unread,
Feb 12, 2002, 1:47:15 PM2/12/02
to
"James Kuyper Jr." <kuy...@wizard.net> wrote in message
news:3C69212D...@wizard.net...

If we do not know that it is verified, we should assume that it is?

That is the opposite of a scientific approach. We may as well stop
searching for the truth/falsity of Reimann's Hypothesis about the Zeta
function or Goldbach's conjecture.

We simply assume that they are true and go on about our business. After
all, it seems that they are likely. Now, we don't know if either of those
two things are true. Do we call them true anyway, since they seem
plausible?

Is "conjectured" behavior defined behavior? It seems clear to me that it
cannot be. Don't imagine that I cannot see that we cannot prove all things.
But I think that the only things that are proven are those we actually
bother to find the answers. All other things are unproven assumptions.

Barry Margolin

unread,
Feb 12, 2002, 2:37:41 PM2/12/02
to
In article <a49kb...@enews2.newsguy.com>,

Dann Corbit <dco...@connx.com> wrote:
>Accept what? I have a object module with a function called clrscr() in it.
>Maybe it's from a vendor. Maybe I compiled it myself. Maybe I downloaded
>it from Simtel. Maybe I can't even remember. The question is: "What does
>it do?" The answer is...
>Not defined by the C language unless I have the source code.

If it was written in C, it does whatever the original source code
indicated. If that original C code was well defined, then calling the
function from another source file can't make that second program undefined.
You don't have to *have* the source code to know that this relationship
holds. You only need the other source code if you need to confirm that it
was well defined.

Barry Margolin

unread,
Feb 12, 2002, 2:53:31 PM2/12/02
to

The C standard doesn't tell you precisely what it does, except that it does
whatever you could determine *if* you had a copy of the source code.
Practically, it's reasonable to assume that the documentation of the
library is a description of that behavior.

If you need independent confirmation, then you do indeed need the source.
But in general you don't.

For that matter, how do you know that your favorite C implementation is
actually conforming? The standard only requires that it be able to process
one conforming program that doesn't exceed certain limits, but that's
obviously not sufficient for real use -- you expect it to be able to do the
right thing with just about any conforming program. There's no way to
verify that it will properly compile every conforming program, but you have
to assume that it does what the vendor claims.

Barry Margolin

unread,
Feb 12, 2002, 2:58:31 PM2/12/02
to
In article <a4bne...@enews1.newsguy.com>,

Dann Corbit <dco...@connx.com> wrote:
>I think that the second is logical and the first is illogical. I am not
>saying that undefined behavior is not useful. Only that if you can't prove
>it, you can't know it. It's only a guess.

It's a wrong guess. There are lots of things we know but can't prove.

Like the "tree falling in the forest" thing. We all know that it makes a
sound, whether there's someone around to hear it or not.

Barry Margolin

unread,
Feb 12, 2002, 2:59:56 PM2/12/02
to
In article <a4bno...@enews1.newsguy.com>,

Dann Corbit <dco...@connx.com> wrote:
>If we do not know that it is verified, we should assume that it is?

You already make that assumption about the implementation (i.e. it's
conforming if the vendor says it is), why not for object files?

Barry Margolin

unread,
Feb 12, 2002, 3:09:16 PM2/12/02
to
In article <a4bhsq$1ci4oh$2...@ID-125440.news.dfncis.de>,

This is where credibility judgement must be applied. If something is too
good to be true (like the fact that Fermat had a proof of his conjecture,
even though the mathematics of his day did not provide any of the tools
needed, and hundreds of mathematicians since could not rediscover it) then
there's a good chance it's false.

But many statements are credible, and don't require proof. If I tell you
"the earth will keep turning tomorrow", you'll believe me. I can't prove
it, and it's even remotely possible that it's false (a meteor could strike
the earth), but it's credible.

The same goes with a vendor claiming that their compiler is conformant or
their library is generated from conforming C code. These are believable
statements, and if the vendor making the claims is trustworthy, there's no
reason to expect them to be false. You can't prove everything, because
eventually you have to reduce things to axioms that, by definition, can't
be proved.

Nils Goesche

unread,
Feb 12, 2002, 3:36:56 PM2/12/02
to
In article <MDea8.14$Un4.41282@burlma1-snr2>, Barry Margolin wrote:
> In article <a4bhsq$1ci4oh$2...@ID-125440.news.dfncis.de>,
> Nils Goesche <car...@cartan.de> wrote:

>>Somehow this reminds me of Fermat's conjecture, sometimes called his
>>``Last Theorem''. By this logic, it wasn't a conjecture until Andrew
>>Wiles proved it for all to see, but should have been considered proven
>>all the time because there once was a proof in Fermat's head :-)
>
> This is where credibility judgement must be applied. If something is too
> good to be true (like the fact that Fermat had a proof of his conjecture,
> even though the mathematics of his day did not provide any of the tools
> needed, and hundreds of mathematicians since could not rediscover it) then
> there's a good chance it's false.
>
> But many statements are credible, and don't require proof. If I tell you
> "the earth will keep turning tomorrow", you'll believe me. I can't prove
> it, and it's even remotely possible that it's false (a meteor could strike
> the earth), but it's credible.

Ok.

> The same goes with a vendor claiming that their compiler is conformant or
> their library is generated from conforming C code. These are believable
> statements, and if the vendor making the claims is trustworthy, there's no
> reason to expect them to be false.

You would really believe a ``venduh'' who claims his library is written
in ANSI compliant C code? You must have had *much* better experiences
with 3rd party code than I, then :-)

> You can't prove everything, because eventually you have to reduce
> things to axioms that, by definition, can't be proved.

Undoubtedly. But it is ourselves who decide when something is an
axiom or something that had better be proven wrt more lower-level
axioms.

Dann Corbit

unread,
Feb 12, 2002, 3:20:25 PM2/12/02
to
"Barry Margolin" <bar...@genuity.net> wrote in message
news:9aea8.10$Un4.38090@burlma1-snr2...

> In article <a49kb...@enews2.newsguy.com>,
> Dann Corbit <dco...@connx.com> wrote:
> >Accept what? I have a object module with a function called clrscr() in
it.
> >Maybe it's from a vendor. Maybe I compiled it myself. Maybe I
downloaded
> >it from Simtel. Maybe I can't even remember. The question is: "What
does
> >it do?" The answer is...
> >Not defined by the C language unless I have the source code.
>
> If it was written in C, it does whatever the original source code
> indicated. If that original C code was well defined, then calling the
> function from another source file can't make that second program
undefined.
> You don't have to *have* the source code to know that this relationship
> holds. You only need the other source code if you need to confirm that it
> was well defined.


I am willing to accept on faith that which is defined by a standard. For
instance, I do not need the source code for printf() in order for me to use
it and believe that the behavior is defined. That is because the behavior
is legislated by the C standard.

On the other hand, if I link in some program module or use a system someone
else has written, then I think that the behavior may be useful but is
undefined. Whether I take a drastic step like that will depend on a number
of things, such as need for this extra functionality and trust in the vendor
of the product.

Undefined behavior does not mean that nasal demons *must* fly out of my
nose. Only that they might.

If I send you a binary program, you have no way of knowing whether or not I
did this:

void main(void)
{
return i = i++;
}

(unless of course the uninitialzed variable traps or the lack of a sequence
point causes a crash on a multiple CPU system or you use the return of
main()).

If the behavior needs no explanation, then why bother explaining it at all?
If we do not need to codify exactly what a program is to perform like, then
the standard has no meaning. After all, if we can simply assume that
behavior is defined without any proof at all, then the behavior *instantly*
becomes defined if I simply refuse to show you the sources.

I guess it's "innocent until proven guilty" in the case of the C language
standard, then. Works well in a court of law, but I would not want to ride
in elevators that depend on that level of confidence for control.

Dann Corbit

unread,
Feb 12, 2002, 3:33:29 PM2/12/02
to
"Barry Margolin" <bar...@genuity.net> wrote in message
news:0vea8.13$Un4.40933@burlma1-snr2...

> In article <a4bno...@enews1.newsguy.com>,
> Dann Corbit <dco...@connx.com> wrote:
> >If we do not know that it is verified, we should assume that it is?
>
> You already make that assumption about the implementation (i.e. it's
> conforming if the vendor says it is), why not for object files?


Why trust the compiler:
1. Because the vendor is bound by the rules of the C language standard
(unless they create and document extensions).
2. Because I can take action if the vendor says that it conforms and yet it
does not.
3. Because the exact behavior of the C language is specified by a document
which I can use to verify correctness.

Why not assume an {arbitrary} object/library results in defined behavior:
1. Human memory is faulty.
2. Because an object module cannot be reverse engineered to produce the
source and is therefore impossible to verify.
3. Because there are multitudes of conditions under which problems can
arise with objects (already stated many times elsewhere)
4. Because important systems may mean people's lives, may mean people's
money, may mean people's jobs, etc.
5. Because in the absence of evidence about correctness, it is bad thinking
to assume it.

There is a reason that we find stamp marks on the heads of bolts. Now,
these stamp marks to not *prove* that the bolt meets the specifications.
But they are a claim by the vendor that they do. If they fail to meet the
specifications, then we have something actionable.

Now, if I use software components where I simply cannot verify the
correctness and (in addition) the exact behavior is not formally documented
by a legal document of some sort, then calling that "defined behavior" is
irresponsible.

This does not mean that I will never do that. But I will also be aware that
in doing so, I am taking a measured risk. In order to take this risk, the
benefits must outweigh the potential pitfalls. Perhaps I must draw graphics
on the screen. I will obviously depend on some outside library. Since it
is *impossible* to do this without going beyond the boundaries of the C
language, I will go ahead and use the outside library. If possible, I will
use the best available (highest quality) standard outside of the C language
to cover it. Even at that, it may be necessary to use a standard not
covered by any government agency or formal defining body. If I must do so
anyway to create a product that satisfies the real needs of the client, then
that is what I will do. But I will not assume that all behaviors are
defined for code which I cannot see. I think that is a big mistake.

Niklas Matthies

unread,
Feb 12, 2002, 4:00:14 PM2/12/02
to
On Tue, 12 Feb 2002 10:42:09 -0800, Dann Corbit <dco...@connx.com> wrote:
[毽愍

> I guess there are two camps of interpretation.
>
> Camp 1: It does not matter if you can verify it or not. As long as it
> works, it is defined behavior.

Wrong. Defined behavior doesn't follow from the fact that "it works".
It only follows from the conformance of the C implementation that is
used and from the translation units fed to this implementation.

Once the translation units are fed to the implementation, the only thing
that can change the definedness of behavior is to somehow break the
implementation to make it non-conforming. For example by replacing some
of its constituents, possibly including the implementation-specific
representation of the program being translated or executed, by
constituents of some other implementation.

-- Niklas Matthies
--
Let he who hath no sin cast the first stone.
Then run ;-).

Barry Margolin

unread,
Feb 12, 2002, 4:28:15 PM2/12/02
to
In article <a4btv...@enews3.newsguy.com>,

Dann Corbit <dco...@connx.com> wrote:
>"Barry Margolin" <bar...@genuity.net> wrote in message
>news:0vea8.13$Un4.40933@burlma1-snr2...
>> In article <a4bno...@enews1.newsguy.com>,
>> Dann Corbit <dco...@connx.com> wrote:
>> >If we do not know that it is verified, we should assume that it is?
>>
>> You already make that assumption about the implementation (i.e. it's
>> conforming if the vendor says it is), why not for object files?
>
>
>Why trust the compiler:
>1. Because the vendor is bound by the rules of the C language standard
>(unless they create and document extensions).
>2. Because I can take action if the vendor says that it conforms and yet it
>does not.

First you have to prove that it doesn't.

>3. Because the exact behavior of the C language is specified by a document
>which I can use to verify correctness.

No you can't. Just because it passes a validation suite doesn't mean that
it will work correctly for all conforming programs, it just means that it
works for those programs in the suite. Haven't you ever heard of vendors
that cook their implementations just so that they'll look good in
well-known benchmarks? The same can be done for validation suites.

>Why not assume an {arbitrary} object/library results in defined behavior:
>1. Human memory is faulty.
>2. Because an object module cannot be reverse engineered to produce the
>source and is therefore impossible to verify.

You don't need to. The documentation of clrscr() presumably says that it
clears the screen. If you call it and your screen doesn't clear, you've
proven that it doesn't work.

This is exactly the same as verifying the compiler: you can't prove that
it's conforming, you can only discover when it's not.

>There is a reason that we find stamp marks on the heads of bolts. Now,
>these stamp marks to not *prove* that the bolt meets the specifications.
>But they are a claim by the vendor that they do. If they fail to meet the
>specifications, then we have something actionable.
>
>Now, if I use software components where I simply cannot verify the
>correctness and (in addition) the exact behavior is not formally documented
>by a legal document of some sort, then calling that "defined behavior" is
>irresponsible.

Why do you consider a statement "Compiler X implements ISO C" any more
valid than "The clrscr() function in this library clears the screen, and
may be treated as if it were written in conforming C"? They're both just
claims by a vendor.

Barry Margolin

unread,
Feb 12, 2002, 4:45:56 PM2/12/02
to
In article <a4bud8$1dj8t7$1...@ID-125440.news.dfncis.de>,

Nils Goesche <car...@cartan.de> wrote:
>You would really believe a ``venduh'' who claims his library is written
>in ANSI compliant C code? You must have had *much* better experiences
>with 3rd party code than I, then :-)

Well, I believe it as much as I believe a vendor who claims that their
compiler is a complete and perfect implementation of the C standard.
Nothing is perfect, we just do the best we can and hope our vendors have
done the same.

Actually, I doubt that most libraries are written in ANSI compliant C code,
since the ANSI standard is so limited. Clrscr() probably has to use some
OS functions that go beyond the standard.

But these libraries can generally be treated *as if* they were ANSI
compliant. They're generally black boxes that just have some action that's
well defined by their documentation, and doesn't impact whether the rest of
your program behaves according to the standard.

Yes, it's possible for some libraries to be less well behaved. There are
CPU architectures that allow you to change byte order (from big-endian to
little-endian) on the fly, and if a program called a function that switches
this all its multi-byte variables would stop working as prescribed by the C
standard.

Here's another way to look at this issue. Remember when Y2K was coming
around, and everyone was working on being Y2K compliant? If you wrote your
own software, you had to confirm that it didn't have any Y2K bugs. But if
you purchased software, all you needed to cover your ass was a statement
from the vendor that the version you're running is Y2K compliant. If it
turned out that your entire system wasn't compliant, and it was due to a
failure on their part, they were liable, not you -- you did your due
diligence by getting the statement from them. You weren't required to dive
into the vendor's source code to verify Y2K compliance yourself.

The same thing goes for C conformance: Your only responsibility is making
your source code conforming and getting assuranced from the vendors that
they did their part right.

It is loading more messages.
0 new messages