Subj : Re: Any help on why? To : borland.public.cpp.borlandcpp From : Bob Gonder Date : Thu Jul 08 2004 07:58 pm Wayne A. King wrote: >On Thu, 08 Jul 2004 10:29:37 -0700, Bob Gonder >wrote: > >>The OP reports that LX works for his 5.02 app. > >Again a misuse of specifiers. "L" is intended for use with long doubles, Only when applied to float formats. for integer formats including X, it is long long (or int64) > The side effects are unknown and not always >immediately apparent. (e.g. - possible corruption of adjacent memory or >the stack, Totally bogus . The caller is responsible for the stack, and the caller knows full well what it put on the stack, and how to remove it. No corruption CAN occur as the stack data is const. If it DOES occur, then the RTL is broken. I really, really, expect better of you Wayne. >>you can only use the >>_sizes_ that are implimented. But what you pack into that _size_ >>agument on the stack can be Anything (that fits). > >See above. You're recommending using a wrong size modifier. See yourself. L is 64 bits for int formats, not 80. >I clearly alluded to the parsing of the source code. The parser can tell >from the source that a type mismatch is present, and freely choose to >ignore it, alter it, pass it unchanged, etc. The effects of mismatching are >unpredictable. Wrongo. Again. Wayne. (At least, in this world) The *compiler* knows *nothing* (see code at end). It passes a String. The RTL Parses the String. The Data is already on the Stack! The RTL Knows Nothing about What got put on the Stack. It can only Assume that the programmer did a good job of it. C ain't type safe. I hope it never becomes type safe. >>I'd like to know _how_ a printf runtime implimentor, who's only input >>is a string and an unknown bunch of binary data on the stack, can >>distinguish between an apple and an orange. > >The parser can distinguish an integer from a float type. It's looking >at the source code, not the stack. The Compiler Parser? I've yet to see a compiler do anything other than pass the string to the RTL. >X is specifically intended for use with ints. If you pass a float to it the >parser can detect that. (As shown in the warnings from CLint++.) LINT ISN'T A C COMPLIER! The C Compiler DOESN'T KNOW OR CARE! >If the parser chooses to process it anyway as raw bits, you got lucky. How is it "lucky" to rely on the RTL to Do It's Job? >But the parser may also choose to silently ignore it, or assume an >int of a different size, etc. Tell me Wayne, How Can It Assume a Different Size from what the Published Size is??????? You've NEVER Answered That! > The parser may be written to determine >correctly the sizes of integer arguments when processing X, and may >assume a default size if passed an illegal type. The effects are >unpredictable, undefined and unreliable. Un-believable. If the compiler doesn't do what I tell it to do, then it is broken. It can't decide on it's own that it knows what's good for the program(mer). You can't have compilers going around saying, Oh, he said it was a DWORD, but I know he meant Long Unicode. >>printf ain't type-safe C++, > >That's no excuse for abusing it. It ain't abuse if it was designed that way. >>Which is also why you shouldn't lie to him >: >"lie"?? That implies deliberate deception and impugns my integrity. >Personal insults are not welcome in these newsgroups. Yeah, I hate doing that. I know you mean well, but it gets under my skin when you (of all people) say "can't" like it doesn't work, when you "can", and it does work. Your below is better. But still should be "shouldn't". >Fine. If you need it qualified: He can't use %X on non-ints and: >(1) expect reliable, consistent, predictable results >(2) expect to do so with impunity >(3) expect any degree of portability in his code >(4) be considered a competent C programmer > > >>So, _I_ think that this usage _was_ intended. > >I suspect you're alone in this world on that assumption. I doubt that, but I'll let it drop. >Sure. Give him enough rope and he'll shoot himself in the foot. That's what I like about C. Almost as good for foot shooting as ASM. >Perverting the language may have its appeal for quick and >dirty programs (programmers?), but it is not a practice to be >encouraged widely. Neophyte C programmers should be >taught and encouraged to use the language as designed >and in a safe and reliable manner. After they've become >competent in the "correct" use of the language, they can >then safely explore aberrations from a solid base to which >they can (and should) return as soon as possible. Yep. Just gotta know when and how to bend those rules, and what "works". Reminding those neophytes that what they are trying is non-portable or non-standard should be enough though. It's like telling a teenager he "can't" take his motorcylcle apart. Maybe he "shouldn't", but he's going to learn quite a lot by doing it. >Are you suggesting that compiler writers don't have brains? I sometimes wonder when I look as the asm output.....Other times, I go WOW! I'd never come up with that! Like a lot of the small multiplies being done by addressing functions and additions instead of the slower mul. >Passing a non-int to a function such as printf when only an >int is expected presumes that the implementation has been >coded to determine correctly the size of *all* types. No, it presumes that the implementation has been coded to follow the rules as published in the acompanying docs about format specifiers. To wit: %LX prints the hex of an int64 (the next 64 bits on the stack). HOW those 64bits Got on the stack is none of the RTL's concern. > It may >not have been designed to do that. It may use a default size >if the arg passed is not an integer type Again, How does the RTL Know what was passed? It Doesn't. It just processes the format string, and applies it to the binary data on the stack. > This may or may not >happily coincide with the incorrect type of arg being passed. If the programmer is any good, it Will coincide. >For efficiency, C library functions are "bare bones" implementations. >They place the burden of responsibility for correct usage squarely >on the programmer. Exactly. >>"Warning" because the programmer _might_ know what he's doing. > >Most unlikely. But not _always_, which is why it _is_ allowed, _is_ only a warning, and _not_ an Error. >>Otherwise, it'd be an "Error". > >Right. Passing incorrect specifiers to printf won't cause a compile >to abort. It *will* usually cause the program to malfunction when "Might" cause incorrect output, but not if the programmer knows what he's doing. And no malfunction at all unless using sprintf type and the output string is decoded or otherwise programically relied upon elsewhere.Well, I can think one _one exception..if the printf also has a float conversion and the values are misalligned. >run. Passing the incorrect number of arguments or specifiers will >also pass undetected in most compilers. That doesn't mean it may All compilers by definition of the function. See code below. >be due to "cleverness" on the part of the programmer. Doesn't rule it out either, which is the real point. - - - - You keep going on how the "parser" is going to see the parameter types and magically change the format specifier. (I assume you are talking about the compiler parser, because the RTL parser Never sees the source!) Well, it can't. It's not allowed. char format[1024]; ReadFile( f, format, whatever printf( format, intval1,dblval2); So tell me how it's going to figure that out? How's it going to "know" that dblval2 is "supposed" to be an int? Can't do anything but be a good little compiler, and push the values and the string. The RTL can't do anything other than parse the string and apply the formats to what is now just a block of binary on the stack. End of story. End of thread. (This message alone took 3 hours, and I need to get back to work as another bug crept in. A feature went missing.) .