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


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

Re: Smaller C compiler

Newsgroups comp.os.msdos.programmer
Date 2013-12-07 16:34 -0800
References (7 earlier) <op.w7maeppv5zc71u@localhost> <943963d2-d981-4863-831f-c74b57a4db75@googlegroups.com> <op.w7ok18e05zc71u@localhost> <b2b9f18d-6cde-44d0-97ff-eb02a2a83e67@googlegroups.com> <op.w7qjvbdi5zc71u@localhost>
Message-ID <92e0fc2b-68e7-41c4-a5ae-e1469f7047fa@googlegroups.com> (permalink)
Subject Re: Smaller C compiler
From "Alexei A. Frounze" <alexfrunews@gmail.com>

Show all headers | View raw


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.

> If the OW compiler had determined a type mismatch, it would've
> warned about it.  I.e., this implies it views the types as equivalent
> or as a valid conversion, or promotion.

In this case a conforming compiler is not required to tell you of undefined behavior when it sees it, it's not even required to look for it. And in other cases it may be simply impossible for the compiler to find UB.

So, if OW doesn't warn you, use a better compiler. See how properly tuned gcc detects this:
http://ideone.com/sOGFFP

and that's despite int and long having the same size in ideone's gcc:
http://ideone.com/iKnXJP

> 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. And if you've only put there (on the stack) an int (16-bit in this case), you're rightly screwed.

> 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.

> >> >> wcl386/l=dos4g
> >> >>
> >> >> ~0u             ffffffff
> >> >> ~0u<<31         80000000
> >> >> ~0u<<32         ffffffff
> >> >> ~0u<<8<<12<<11  80000000
> >> >> ~0u<<8<<12<<12  00000000
> >> >>
> >> >> Obviously, some things are not correct or computing as expected.
> >> >
> >> > For one thing, you shouldn't be expecting much from shifting a
> >> > 16-bit int by 16 bit positions or from shifting a 32-bit int by
> >> > 32 bit positions. Both invoke undefined behavior.
> >> >
> >>
> >> I shouldn't?  You're the one doing so... <<8<<12<<12.  Yes?
> >
> > Yes and no. <<8<<12<<12 isn't necessarily equivalent to <<(8+12+12).
> 
> 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.

> 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.

<<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.

> 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.

> > 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]

> > 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.

> The C compiler is required to implement the total shift count using as
> many assembly instructions as is needed.  The C compiler can't just
> ignore 3 bits of shift for <<8 by truncating it to <<5 because
> the CPU only supports <<5...

The compiler can ignore bits if the count is too big or negative. If the count is in the valid range, there's nothing to ignore.

> > 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.

> 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. That's your:

~0u<<32         ffffffff 

> 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. You have produced and seen it yourself:

~0u<<32         ffffffff 

And here's the exact same UB from gcc with me forcing it to happen:
http://ideone.com/iKnXJP

And without forcing, it just fails to compile:
http://ideone.com/6lB1hh

Alex

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