Is this program standard conform?

P

Peter Nilsson

Army1987 said:
Peter said:
Army1987 wrote:
Keith Thompson wrote:
Just recently we've seen three examples of lcc-win
features that violate the standard: your "%b" format
for printf

Why?
7.19.6.1:
"9   If a conversion specification is invalid, the
behavior is undefined."

Lowercase conversion specifiers are reserved for future use
[cf 7.26.9.] If lcc-win used %B instead, it would be fine.

So? I think it's not broken *yet*, since as of C99 + TC3
(i.e. n1256), a program with printf("%b"); is allowed to do
anything.

The issue is whether Jacob's implementation (which claims
conformance) has the right to define a behaviour for %b.
It does not.
For example, glibc's printf() prints strerror(errno) with
the %m specifier.

That too is broken.
Yes, using capitals would lower the chances for it to be
broken *in future*,

You miss the point of some of the standard's reservations.
They allow the committee to make choices that aren't already
tainted with widespread differences, viz snprintf.

But it's not just conversion specifiers with lcc-win, it's
length modifiers as well. Though Jacob at least asked last
time before he ignored advice...

"So many people has stolen the extra format characters for
various purposes that we actually had a hard time finding
one for use with fixed-point types in the embeded systems
TR. Since whoever uses these extensions surely cannot
expect other printf implementations to uderstand them, no
portability purpose is achieved by adding them to printf."
- Doug Gwyn, csc
but as it stands, it is not one of the
reasons why lcc-win32 is broken.

It is certainly not one of the main reasons. Nevertheless,
using a facet that implementors are specifically asked _not_
to use potentially undermines future standards. This is
ironic from a person who claims to want to improve the C
language.
 
R

Randy Howard

Fumeur said:
Is the following program standard conform?
(reduced as much as possible so it still shows the problem)

/* begin */
#include <stdio.h>

void xfprintf(FILE *);

void xfprintf(FILE *f) {
fprintf(f, "x\n");
}

int main(void) {
xfprintf(stderr);
return 0;
}
/* end */


It compiles with gcc without warnings and works correctly, but trying
to compile it with a particular other popular compiler, it yields the
following diagnostics:

lc -ansic -A -shadows -unused -O -c xfprintf.c -o xfprintf.obj
Error xfprintf.c: 4 redefinition of 'xfprintf'
Error c:\lcc\include\stdio.h: 116 Previous definition of 'xfprintf' here
2 errors, 0 warnings
1 error
make: *** [xfprintf.obj] Error 1

Who is at fault here, my program or the compiler?

You are using a bad bad compiler. This is unacceptable!

Am I to understand that this is your response to a valid test case
submission?
I would ask

1) For a full refund of the money you spent.

*After* you get the money :)

2) Ask Ossama bin laden to kill that infidel to the principles
and spirit of C.

Well, that's professional. I can see why it is so widely used.
 
K

Keith Thompson

Army1987 said:
Why?
7.19.6.1:
"9 If a conversion specification is invalid, the behavior is undefined."

There's a footnote attached to the line you quoted:

See future library directions (7.26.9).

7.26.9 says:

Lowercase letters may be added to the conversion specifiers and
length modifiers in fprintf and fscanf. Other characters may be
used in extensions.

This was discussed here just recently. The use of "%b" as an
extension doesn't break any existing portable code, but a future
version of the standard could break the implementation.
 
K

Keith Thompson

jacob navia said:
Of course it is undefined but there people
that insist that lcc-win is the devil.

Yeah... I am a sinner...

I will go to C's heretics hell probably condemned to use gcc -v
for all eternity...

jacob, you need to take a break. Seriously.
 
A

Army1987

Peter said:
Army1987 said:
Peter Nilsson wrote:
Lowercase conversion specifiers are reserved for future use
[cf 7.26.9.] If lcc-win used %B instead, it would be fine.

So? I think it's not broken *yet*, since as of C99 + TC3
(i.e. n1256), a program with printf("%b"); is allowed to do
anything.

The issue is whether Jacob's implementation (which claims
conformance) has the right to define a behaviour for %b.
It does not.
For example, glibc's printf() prints strerror(errno) with
the %m specifier.

That too is broken.

I think I'm missing a point.
7.19.6.1 says: "If a conversion specification is invalid, the behavior is
undefined.".
3.7.1 defines "undefined behavior" as "behavior, upon use of a
nonportable or erroneous program construct or of erroneous data, for which
this International Standard imposes no requirements".

So if I'm right, if a program contains:
printf("%m");
anything it might do wouldn't violate the standard. This includes printing
strerror(errno).

If I'm wrong, what is a conforming implementation allowed to do when
executing the statement above, and what is it forbidden to do?

(Of course I'm using "broken" to mean "not conforming". Your point can
still be valid if you mean something else by it. Is this the case?)
 
K

Keith Thompson

Army1987 said:
Peter said:
Army1987 said:
Peter Nilsson wrote:
Lowercase conversion specifiers are reserved for future use
[cf 7.26.9.] If lcc-win used %B instead, it would be fine.

So? I think it's not broken *yet*, since as of C99 + TC3
(i.e. n1256), a program with printf("%b"); is allowed to do
anything.

The issue is whether Jacob's implementation (which claims
conformance) has the right to define a behaviour for %b.
It does not.
For example, glibc's printf() prints strerror(errno) with
the %m specifier.

That too is broken.

I think I'm missing a point.
7.19.6.1 says: "If a conversion specification is invalid, the behavior is
undefined.".
3.7.1 defines "undefined behavior" as "behavior, upon use of a
nonportable or erroneous program construct or of erroneous data, for which
this International Standard imposes no requirements".

So if I'm right, if a program contains:
printf("%m");
anything it might do wouldn't violate the standard. This includes printing
strerror(errno).

If I'm wrong, what is a conforming implementation allowed to do when
executing the statement above, and what is it forbidden to do?

(Of course I'm using "broken" to mean "not conforming". Your point can
still be valid if you mean something else by it. Is this the case?)

You're right. As far as I can tell, using "%b" as an extension to
print a value in binary doesn't render the compiler non-conforming.
So my statement upthread that this violates the standard was
incorrect. Sorry about that.

But as C99 7.26.9p1 says (under "Future library directions"):

Lowercase letters may be added to the conversion specifiers and
length modifiers in fprintf and fscanf. Other characters may be
used in extensions.

Given the above, I'd say that last sentence is more of a
recommendation than a requirement. I note that it doesn't say that
lowercase letters may not be used in extensions, only that other
characters may be used.

Implementations don't *have* to avoid using lowercase letters for
extensions in fprintf and fscanf, but they should.

jacob's response when this was brought up a week or so ago was quite
reasonable:

| Obvious: I did not know that. Since this is a very minor extension
| maybe I can just change it, but if people use it they will complain
|
| Stupid error from my part.

(I'm not saying it really was a stupid error, merely that jacob was
reasonable about admitting that it was an error.)
 

Ask a Question

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

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

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,591
Members
45,103
Latest member
VinaykumarnNevatia
Top