Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.os.msdos.programmer > #1140

Re: Smaller C compiler

From "Rod Pemberton" <dont_use_email@xnohavenotit.cnm>
Newsgroups comp.os.msdos.programmer
Subject Re: Smaller C compiler
Date 2013-12-08 02:12 -0500
Organization Aioe.org NNTP Server
Message-ID <op.w7riacro5zc71u@localhost> (permalink)
References (8 earlier) <943963d2-d981-4863-831f-c74b57a4db75@googlegroups.com> <op.w7ok18e05zc71u@localhost> <b2b9f18d-6cde-44d0-97ff-eb02a2a83e67@googlegroups.com> <op.w7qjvbdi5zc71u@localhost> <92e0fc2b-68e7-41c4-a5ae-e1469f7047fa@googlegroups.com>

Show all headers | View raw


On Sat, 07 Dec 2013 19:34:58 -0500, Alexei A. Frounze  
<alexfrunews@gmail.com> wrote:
> On Saturday, December 7, 2013 10:48:37 AM UTC-8, Rod Pemberton wrote:
>> On Sat, 07 Dec 2013 01:23:14 -0500, Alexei A. Frounze
>> <...@gmail.com> wrote:
>> > On Friday, December 6, 2013 9:19:10 AM UTC-8, Rod Pemberton wrote:
>> >> On Fri, 06 Dec 2013 00:37:26 -0500, Alexei A. Frounze
>> >> <...@gmail.com> wrote:
>> >> > On Thursday, December 5, 2013 3:33:51 AM UTC-8, Rod Pemberton  
>> wrote:

>> >> >> OpenWatcom v1.3 results of ~0u and with shifts:
>> >> >>
>> >> >> wcl/l=dos
>> >> >>
>> >> >> ~0u         8000ffff
>> >> >> ~0u<<15     80000000
>> >> >> ~0u<<16         0000
>> >> >> ~0u<<8<<7       0002
>> >> >> ~0u<<8<<8       6322 or 6333
>> >> >
>> >> > How come 16-bit ints look like 32-bit? Where's the garbage coming
>> >> from?
>> >> > I mean "8000" in "8000ffff".
>> >> >
>> >>
>> >> It's coming from the program when it prints the value.
>> >>
>> >> Specifically, it's from a "%04lx" to a printf().  It overflowed.  >>  
>> E.g.,
>> >>
>> >>    printf("%04lx\n",~0u);
>> >>
>> >> Yes, in theory, it should truncate to only four digits for display...
>> >
>> > In theory and in practice you shouldn't lie to printf() about the
>> > type of the optional parameters. If you write "%lx" but then supply
>> > something that's not a long integer (unsigned, AFAIR), you get
>> > undefined behavior from printf(). 0 and 0u are an int and an unsigned
>> > int, and not any kind of long int.
>> >
>>
>> As a practical matter, with or without a cast, the argument is converted
>> to a hex unsigned long for display by the compiler.  Whether that
>> conversion is officially classified as "undefined behavior", or
>> classified as an "implicit cast", it should still convert types
>> correctly for the situation, or it should cause compilation to error.
>
> You are wrong. Optional arguments (that fall under '...') do not get  
> converted from int to long, neither when passed to the function nor when  
> already in the function just for your convenience to choose at will  
> between %d and %l. You can only get away with printf'ing ints as longs  
> (or the other way around) when their sizes are the same, as I've already  
> mentioned.
>

See below.

>> If a cast or "%hx" or &0xFFFF had been used, you might not have seen  
>> this issue.  To me, the 8-digit displayed values implies the compiler
>> is actually using a 32-bit signed type for ~0u and etc values instead
>> of 16-bit unsigned.
>
> It's not that. It's that when printf() looks at the format and
> sees %lx in it, it grabs a long int (32-bit in this case) from
> the stack.

C doesn't have a stack officially.  So, how can printf() grab a
long from something that officially doesn't exist?  ;-)  The
specific implementation may have a stack and printf() may obtain
a long from from it.  That doesn't mean there is a mismatch in
type sizes.

Of course, the majority of C compilers use a stack.  It allows
for recursion to be implemented easily.

Anyway, I believe the compiler should've converted the type.

E.g., from Harbison & Steele, "C:A Reference Manual", 3rd, ed.:

"An actual argument to a function may be implicitly converted
to another type prior to the function call."

I.e., even if not always implicitly converted, it may be sometimes.
Meaning one compiler can while another might not.

Also, on integer conversions:

"If the destination type is longer than the source type, then
the only case in which the source value will not be representable
in the result type is when a negative signed value is converted
to a longer, unsigned type."

Of course, the source type to "%04lx" is a 16-bit unsigned and
is converted to a unsigned destination type, likely longer.

So, that and other similar statements in H&S are in the C
specification somewhere, most likely with different wording.

>> When the converted result fits into the display format "%04lx",
>> which is defined behavior, we're seeing four digits as expected.
>> When the converted result doesn't fit the display format, which
>> is officially undefined behavior, e.g., when signed or larger
>> than 64K, it displays the entire, non-truncated, value using
>> eight digits.
>
> Wrong again. C89/C99 on 4 in in your %04lx, quote:
> In no case does a nonexistent or small field width cause truncation
> of a field; if the result of a conversion is wider than the field
> width, the field is expanded to contain the conversion result.
>

Isn't that what I just said?  Try reading it without "non-truncated".
Then, assume the true size is 32-bits - not 16-bits - since that
was my perspective.  Re-read with "non-truncated".

>> Just as you "shouldn't lie to printf", you shouldn't abuse the
>> poorly, and not widely implemented, ANSI C concept of "sequence
>> points" in an attempt to avoid undefined behavior.
>>
>> Alternately, you shouldn't abuse known limits of limits.h to
>> attempt to reason your way around undefined behavior, either.
>
> Irrelevant here.
>

Why? The first is exactly what you're doing, IMO.  Don't you think
that's a possible reason why your code doesn't work?  Personally,
I think it's an more likely error in OW since I found more than
a few, but it's just as plausible that your abuse of the specification
is at fault.  ISTM, you're attempting to bypass behavior which
may not be bypassable on every single compiler.

>> A C compiler is not as smart as you.  It does things one way for
>> all apparently equivalent situations.  It's goal is to get
>> reasonably C compliant assembly in the most sane way possible.
>> So, if undefined behavior exists in one instance, that same undefined
>> behavior situation will likely be valid for other instances which
>> are effectively the same, but not undefined.  I.e., if <<32 on
>> 32-bit is undefined, then effectively <<8<<12<<12 is too.
>
> I don't know if you're just trolling me or indeed do not understand
> (and seem unwilling to learn) how several basic things ought to work
> in C according to the language standard.
>

Yet, even though you know the C's language standard has no defined
stack, you used a stack to justify your earlier logic on how printf()
works and fails...  What did you say about not understanding?  :-)

I'm not trying to troll you.  I'm just not interested in boundary
conditions such as UB, limits.h, or differences of type formats.
I know how the underlying assembly works.  I generally know how
C compilers convert much of the code to assembly.  C has a number
of "dark corners" where real-world C compilers work very differently
 from each other, and where historically implemented things work
differently from the C standards.  I try to avoid those corners.
IMO, that's much better than attempting to master them.

Also, it seems you're not always very clear on what C does and
what assembly does, i.e., sometimes equating/conflating the two.

> <<8<<12<<12 is defined. It may cause UB if the value being shifted
> is of some signed integer type. If you remember, I do this with
> unsigned integers.

Yes, you've technically avoided UB in C by doing small shifts, but
probably haven't avoided UB in reality since the small shifts are
equivalent to large shifts, and you definately haven't avoided
zeroing a 32-bit unsigned integer.

>> This is also an example why you have to consider what is going
>> to be done by the C compiler at the assembly level.  No matter
>> how <<8<<12<<12 is implemented, it will zero a 32-bit integer.
>
> It will zero an unsigned 32-bit int. If the unsigned int is 16-bit,
> it will be zeroes too.
>

Yes.

>> > The restriction on the shift count applies to one shift. Hence, with
>> > unsigned int being at least 16 bits long, I can shift by however many
>> > positions I want, provided that I don't shift by more than 15 at a  
>> time.
>>
>> That officially avoids undefined behavior in C.
>>
>> It doesn't avoid overflowing integers at the assembly level,
>> which someone might claim is the basis for undefined behaviors
>> in C...  ;-)
>
> That does not apply to unsigned int. You're free to overflow
> it in C however you like, the behavior is defined.
>
> [snip]

You seem to be contradicting your earlier statements on UB here.

>> > In most CPUs,
>> > shift instructions only take the least significant bits of the shift
>> > count (4 bits for a shift of a 16-bit value, 5 bits for a shift of a
>> > 32-bit value and so on)
>>
>> Well, it seems to be 5 bits on x86, for both regular and double shifts.
>>
>> > and ignore the rest.
>>
>> The assembly instruction may ignore the remainder of the bits
>> effectively imposing a per instruction shift limit.  That just
>> means more instructions are required to implement larger shifts.
>
> That's the reason for the restriction appearing in the standard. And,  
> transitively, that's the reason for me doing <<8<<12<<12.

Let's start over.  How is <<8<<12<<12 any different from <<32?
Now, exclude C's definition of UB.  Did anything the compiler
does for either change?  Prove it.  Now, prove it for all C
compilers.  You can't.  The C specification doesn't specify
implementation.  The C compiler implements the specification
to the best of the compiler authors' abilities.

>> > So, effectively, your <<32 reduces to shl reg, 0.
>>
>> No.
>
> Why not? It's UB in this case, sure. And the UB in <<32 often manifests  
> in really doing <<(32&31). Most likely that's exactly how you got this  
> with 32-bit int:
>
> ~0u<<32         ffffffff
>
> It is not the only possible way for UB to manifest itself, but it's a  
> common one.
>

"Why not?"

Because what you're effectively claiming is that <<8 or <<12
or <<31 will work but <<32 or <<35 doesn't work simply because
the C specification calls it undefined behavior.  That's really
not how things work.  Do you seriously believe that the compiler
implementor checks for the shift count and decided to stop at 31
or do something special thereafter? No, of course not, they
implemented a generic shift routine independent of shift count.
So, why is <<31 so different from <<32? ...

>> Perhaps, you're thinking of "rol reg" instead of "shl reg"?  ;-)
>>
>> While the effective shift count for "shl reg, 0" is the same
>> as <<32 due to wrap around, "shl reg, 0" doesn't actually *clear*
>> the register.  It leaves it alone.
>
> Precisely.

... which means it's in error.  The behavior is incorrect.
That was stated previously.

>> SHL shifts in a cleared bit
>> per shift.  ROL rotates one bit per shift.
>>
>> A shift left of 32 bits or more will zero a 32-bit register.
>> So, <<32 would effectively reduce to equivalent of 'xor reg, reg',
>> or 'mov reg, 0'.  Of course, most C compilers would use multiple
>> shl shifts to shift 32 times, but some might optimize to a register
>> clear.
>
> Again, if your unsigned int has 32 bits in it, applying <<32 to it is  
> incorrect, it will cause UB, which may not clear said unsigned int.

How is that any different from <<8<<12<<12?  AISI, you could very
well have a C compiler which fails for it too, e.g., converting that
to <<32, or converting both to the same shift sequence in assembly,
if one fails so would the other.  So far, AISI, you've not presented
any justification as to why one sequence *must be* different from
the other in assembly.  My understanding is the compiler is free
to optimized that as long as the code doesn't change semantically.
AFAICT, it doesn't.


Rod Pemberton

Back to comp.os.msdos.programmer | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-01 08:15 -0800
  Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2013-12-01 18:42 +0000
    Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-01 19:14 -0800
      Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2013-12-02 11:13 +0000
        Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-02 03:21 -0800
          Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2013-12-03 06:21 +0000
            Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-02 23:17 -0800
              Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2013-12-03 13:31 +0000
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-03 06:05 -0800
                Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-03 10:47 -0500
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-03 21:18 -0800
  Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-03 12:23 -0500
    Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-03 16:26 -0500
      Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-03 23:58 -0800
        Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-04 04:31 -0500
          Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-04 05:01 -0500
            Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-04 02:20 -0800
              Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-05 06:33 -0500
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-05 21:37 -0800
                Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-06 12:19 -0500
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-06 22:23 -0800
                Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-07 13:48 -0500
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-07 16:34 -0800
                Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-08 02:12 -0500
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-13 03:32 -0800
                Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-15 04:47 -0500
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-15 02:14 -0800
                Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-15 13:21 -0500
          Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-04 23:39 -0800
            Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-05 06:38 -0500
              Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-05 21:40 -0800
              Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-06 04:19 -0800
                Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-06 13:40 -0500
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-14 21:07 -0800
    Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-03 22:22 -0800
      Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-04 04:30 -0500
        Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-04 23:21 -0800
          Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-05 04:23 -0500
            Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-05 21:31 -0800
  Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2013-12-10 04:59 +0000
    Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2013-12-10 06:17 +0000
      Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-11 02:36 -0800
        Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2013-12-11 13:44 +0000
  Re: Smaller C compiler Harry Potter <rose.joseph12@yahoo.com> - 2013-12-10 10:41 -0800
    Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-11 03:06 -0800
      Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-11 10:47 -0500
        Re: Smaller C compiler Harry Potter <rose.joseph12@yahoo.com> - 2013-12-11 08:01 -0800
          Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-11 13:40 -0500
        Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-11 22:07 -0800
        Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-25 02:33 -0800
          Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-29 03:24 -0800
  Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-21 15:55 -0800
  Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2013-12-29 17:16 +0000
    Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2013-12-29 21:54 -0500
      Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-29 19:38 -0800
    Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-29 19:36 -0800
      Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2013-12-30 05:07 +0000
        Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2013-12-29 21:58 -0800
        Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-01-05 19:43 -0800
          Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2014-01-06 15:27 +0000
            Re: Smaller C compiler "Rod Pemberton" <dont_use_email@xnohavenotit.cnm> - 2014-01-06 19:51 -0500
              Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2014-01-07 04:27 +0000
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-01-06 21:52 -0800
          Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-02-16 22:57 -0800
            Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-02-25 00:17 -0800
              Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-03-01 21:31 -0800
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-03-10 01:46 -0700
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-04-20 20:19 -0700
                Re: Smaller C compiler Harry Potter <rose.joseph12@yahoo.com> - 2014-04-23 11:20 -0700
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-04-23 11:41 -0700
                Re: Smaller C compiler Harry Potter <rose.joseph12@yahoo.com> - 2014-04-25 06:08 -0700
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-09-14 03:06 -0700
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-11-09 03:26 -0800
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-11-28 04:06 -0800
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2014-12-21 01:56 -0800
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2015-01-10 10:37 -0800
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2015-04-19 23:55 -0700
                Re: Smaller C compiler "Auric__" <not.my.real@email.address> - 2015-04-22 06:13 +0000
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2015-04-22 00:12 -0700
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2015-04-25 21:11 -0700
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2015-05-16 17:49 -0700
                Re: Smaller C compiler "Bill Buckels" <bbuckels@mts.net> - 2015-05-19 20:01 -0500
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2015-05-19 18:18 -0700
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2015-08-15 02:13 -0700
                Re: Smaller C compiler "Alexei A. Frounze" <alexfrunews@gmail.com> - 2015-09-06 15:55 -0700

csiph-web