ARCHER@segin4.segin.fr (04/10/90)
Christoph van Wuellen <HBO043@DJUKFA11.BITNET> says: CvW> ... WHAT ABOUT CvW> test(a) float a; CvW> { CvW> test1(&a); CvW> } CvW> This certainly passes a pointer to a double, and this can't be changed. CvW> So I ask the C Syntax experts - what do you think a compiler should do CvW> in both cases? I don't think for my compiler :-), but a compiles as a double (sizeof being 8), and *a in test1 has nothing near the same value as a in test: test(a) float a; { a = 0.1; printf("%f\n", a); test1(&a); } test1(a) float *a; { printf("%f\n", *a; } said: 0.1 1.45000 It seems that most compilers do the same kind of thing. So if your compiler enables the user to do some mistakes, you'll lose portability: The program will work compiled with C68, and not with any other compiler. What's more important? Vincent Archer Replies to: archer%segin4.segin.fr@prime.com, NOT archer@segin4.segin.fr
tim@nucleus.amd.com (Tim Olson) (04/11/90)
In article <16383@nigel.udel.EDU> ARCHER@segin4.segin.fr writes: | I don't think for my compiler :-), but a compiles as a double (sizeof being 8), | and *a in test1 has nothing near the same value as a in test: | | test(a) float a; | { | a = 0.1; | printf("%f\n", a); | test1(&a); | } | | test1(a) float *a; | { | printf("%f\n", *a; | } | | said: | | 0.1 | 1.45000 | | | It seems that most compilers do the same kind of thing. So if your compiler | enables the user to do some mistakes, you'll lose portability: The program will | work compiled with C68, and not with any other compiler. What's more important? If you want to start progressing towards ANSI compatibility, then this must be fixed. The Standard says (in the Rationale Section): Some current implementations rewrite the type of a (for instance) |char| parameter as if it were declared |int|, since the argument is known to be passed as an |int| (in the absence of prototypes). The Standard requires, however, that the received argument be converted "as if" by assignment upon function entry. Type rewriting is thus no longer permissible. This means that in: f(c, f) char c; float f; { . . sizeof c should be 1 and sizeof f should be equal to sizeof(float). -- Tim Olson Advanced Micro Devices (tim@amd.com)
ath@prosys.se (Anders Thulin) (04/11/90)
In article <29812@amdcad.AMD.COM> tim@amd.com (Tim Olson) writes: > > [ quote ANSI Rationale deleted ] > >This means that in: > >f(c, f) >char c; >float f; >{ > . > . >sizeof c should be 1 and sizeof f should be equal to sizeof(float). No. The ANSI C standard also tries very hard not to introduce backward incompabilities. The example above works just the way K&R says: c becomes an int, and f a double by widening, provided there isn't a new-style definition of f lurking in some corner. In the presence of a new-style definition, like f(char c, float f); c would indeed be a char and f a float. I can't quote the ANSI gospel, but K&R, 2nd ed, Section A7.3.2 Function calls, p.201-202 provides more info. -- Anders Thulin ath@prosys.se {uunet,mcsun}!sunic!prosys!ath Telelogic Programsystem AB, Teknikringen 2B, S-583 30 Linkoping, Sweden
tim@nucleus.amd.com (Tim Olson) (04/11/90)
In article <460@helios.prosys.se> ath@prosys.se (Anders Thulin) writes: | No. The ANSI C standard also tries very hard not to introduce backward | incompabilities. The example above works just the way K&R says: | c becomes an int, and f a double by widening, provided there isn't | a new-style definition of f lurking in some corner. | | In the presence of a new-style definition, like | | f(char c, float f); | | c would indeed be a char and f a float. | | I can't quote the ANSI gospel, but K&R, 2nd ed, Section A7.3.2 Function | calls, p.201-202 provides more info. This section really only discusses promotion of arguments by the caller, which should be done. However, I was referring to X3J11/88-159 (December 7 draft, just before ratification), which explicitly states (as a noted QUIET CHANGE) that the received, widened argument must be narrowed upon entry, and that type rewriting is not allowed. I checked it with two ANSI-conforming compiler we have here (MetaWare HighC and gcc with -ansi -pedantic flags), and they both agree with this. -- Tim Olson Advanced Micro Devices (tim@amd.com)
HBO043%DJUKFA11.BITNET@cunyvm.cuny.edu (Christoph van Wuellen) (04/11/90)
The point is:
in the sequence
test (a) float a;
{
....
}
I change the ,,float'' to double as soon the argument declarations have
been processed. The same promotions occur for char==>int, short==>int etc.
Now, I am of the opinion that this is correct, although GCC (which I use
as a reference compiler when I am not sure) converts the double back to
a float in the startup code of the function if its address is used somewhere.
I think this is a big mess. It really should be a syntax error to declare
a ,,char'' argument of a function etc. (This might not be true if you use
prototypes that might suppress the default promotions).
My opinion at the moment is that I should not change this in the compiler.
/Christoph van Wuellen
P.S. with char/int it is the same problem if you don't assume that you
can retrieve the char in the low order bits of the int (I wouldn't put
such an assumption into the front end of a compiler)
bill@flash.UUCP (William Swan) (04/12/90)
In article <16383@nigel.udel.EDU> ARCHER@segin4.segin.fr writes: >CvW> ... WHAT ABOUT >CvW> test(a) float a; >CvW> { >CvW> test1(&a); >CvW> } >CvW> This certainly passes a pointer to a double, and this can't be changed. >CvW> So I ask the C Syntax experts - what do you think a compiler should do >CvW> in both cases? I've come a little late into this discussion, and I'm no C Syntax Expert[tm], but I've run into this before. Oddly, this came up on a local BBS this past weekend. The description of the ANSI C standard in K&R 2nd Ed. says, in essence, that float parameters declared "old-style" are promoted to double, those declared "new-style" are not. (K&R C, 2nd Ed. ,p 202, section A7.3.2 Function Calls) In other words: main() { float f; test(&f); } test(f) float *pf; { printf(..., *pf); } will fail, but: main() { float f; test(&f); } test(float *pf) { printf(..., *pf); } will not. -- Bill Swan bill@Summation.WA.COM Send postal address for info: Innocent but in prison in Washington State for 13.5 years (or more): Ms. Debbie Runyan: incarcerated 01/1989, scheduled release 07/2002. In now: 1 year, 2 months, 3 weeks, 1 day.