Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Stupid compiler signs my fast uint's

Name: Anonymous 2009-04-08 16:11

Hello /prog/riders.
I've stumbled upon a problem when I tried to OPTIMIZE a topologic sort function for a geometry package. Here's the gist of it:
extern "C"
{
#include <stdint.h>
}

enum {LEFT = 1u, RIGHT = 2u, BOTH = 3u};

int main()
{
    bool side  = true;
    const bool side_const = true;

    uint_fast8_t n;

    const uint_fast8_t a = side  ? LEFT : RIGHT,
                       b = LEFT;
    const uint_fast8_t A = side_const ? LEFT : RIGHT,
                       B = LEFT;

    uint_fast8_t c = side ? LEFT : RIGHT,
                 d = LEFT;
    uint_fast8_t C = side_const  ? LEFT : RIGHT,
                 D = LEFT;

    n |= a; // warning: conversion to ‘uint_fast8_t’ from ‘int’ may alter its value
    n |= b;
    n |= A;
    n |= B;

    n |= c; // warning: conversion to ‘uint_fast8_t’ from ‘int’ may alter its value
    n |= d; // warning: conversion to ‘uint_fast8_t’ from ‘int’ may alter its value
    n |= C; // warning: conversion to ‘uint_fast8_t’ from ‘int’ may alter its value
    n |= D; // warning: conversion to ‘uint_fast8_t’ from ‘int’ may alter its value

}

As you can see the compiler evaluated the expressions for b,A and B and didn't complain about type conversion. Why then, does it need to convert my fast uints to slow ints in the case of a,c,d,C and D?
I compiled with
$ gcc -std=c++98 -Wconversion bittwiddling.cpp.
My compiler version is
$ gcc -V
gcc (GCC) 4.3.2 20081105 (Red Hat 4.3.2-7)

Name: Anonymous 2009-04-08 16:28

Because the enum isn't unsigned to begin with and the compiler only optimizes where it safely can.

Name: Anonymous 2009-04-08 16:51

>>2
Thanks for the tip.  I've modified the code to pure C:
#include <stdint.h>

const uint_fast8_t LEFT = 1u, RIGHT = 2u, BOTH = 3u;

int main()
{
    uint_fast8_t side = 0;
    const uint_fast8_t side_const = 1;

    uint_fast8_t n;

    // warning: conversion to ‘uint_fast8_t’ from ‘int’ may alter its value
    const uint_fast8_t a = ((side == 0) ? LEFT : RIGHT),  // Here
                       b = LEFT;
    const uint_fast8_t A = ((side_const == 0) ? LEFT : RIGHT), // Here
                       B = LEFT;
    uint_fast8_t c = (0 ? LEFT : RIGHT),
                 d = LEFT;
    uint_fast8_t C = (1 ? LEFT : RIGHT),
                 D = LEFT;

    if(side == 0)
        c = LEFT;
    else
        c = RIGHT;

    n |= a;
    n |= b;
    n |= A;
    n |= B;
    n |= c;
    n |= d;
    n |= C;
    n &= D;
}

The warnings on bitwise operations are gone but now they've moved to the ternary operator. Changing constness on any of the variables doesn't seem to matter. This is weird.

Name: Anonymous 2009-04-08 17:45

That's what you get for using gcc.

Name:   2009-04-08 17:53

Name:    2009-04-08 17:54

 

Name:   2009-04-08 17:55

ಠ_ಠ

Name: zero line post 2009-04-08 17:56

Name: no line in between 2009-04-08 17:57

Name: ಠ_ಠ 2009-04-08 17:58

>>8,9
ಠ_ಠ ಠ_ಠ ಠ_ಠ ಠ_ಠ ಠ_ಠ ಠ_ಠ ಠ_ಠ ಠ_ಠ

Name: Anonymous 2009-04-08 17:59

Integer promotion -- the 8-bit quantities are being widened to int in the expressions.  Try adding explicit casts.

Name: Anonymous 2009-04-08 18:39

>>11
That works but I'm at a loss. Why does the compiler feel the need to promote an integer that isn't being modified? There should be no difference between
if(side == 0)
    c = LEFT;
else
    c = RIGHT;

and
c = (side == 0) ? LEFT : RIGHT
shouldn't it?

Name: Anonymous 2009-04-08 21:49

Try removing -Wall

Name: Anonymous 2009-04-08 22:01

>>13
But it's a supporting -Wall, if I knock that down the whole house will come down.

Name: Anonymous 2009-04-09 0:56

>>12
The compiler does what the ISO standard tells it to.

Now you're programming in C!

Name: Anonymous 2009-04-09 1:16

>>15
s/C/portals

Name: Anonymous 2009-04-09 3:02

== 0

Don't do that.

c = side? RIGHT : LEFT;

Name: Anonymous 2009-04-09 5:50

>>15
I must be doing something wrong, then.
I'll need to check if packing the masks into the fast integer type is worthwhile. If the fast type is going to get promoted to a higher rank int on every bitwise op then I might as well use that rank in the first place.
>>17
I know. I was fighting caffeine deprivation at the time.

Name: REM BBCODE 2009-04-09 6:20

Name: Anonymous 2009-04-09 6:36


Name: Anonymous 2009-04-09 21:25

>>17
What's the difference? It's going to compare to zero anyway.

Name: Anonymous 2009-04-09 22:00

>>21
It's

Name: Anonymous 2009-04-10 10:35

>>18
Look at the ASM output dumbass.

Name: Anonymous 2009-04-10 19:11

>>23
you're

Name: 2009-04-11 15:22

Name: Anonymous 2009-04-29 6:02

>>1
OP, this is vitally important, where did you pick up the phrase "/prog/-riders"? I need to know

Name: Anonymous 2009-04-29 6:04

Name: Anonymous 2009-04-29 6:45

hl=en
what.

Name: Anonymous 2009-04-29 7:08

>>12

C doesn't have a ternary operator... You're going to have to change it to an if statement or use a function.

Name: Anonymous 2009-04-29 7:31

>>29
C doesn't have a ternary operator...
Back to anal, please

Name: Anonymous 2009-04-29 7:32

>>1
Yes, it's always compiler's fault, because compputers tend to do more than they are told to, arbitrarily.

Name: Anonymous 2009-04-29 8:31

Yoshinoya File Download From Rapidshare¹ - 4chan BBS evening prog riders lisplambda ascii pythonlispeat ascii ...

what

¹ http://www.avun.com/Rapidshare.com/yoshinoya.html

Name: Anonymous 2009-04-29 8:54

>>12
the ternany operator is an expression and if-then-else is a statement

Name: Anonymous 2009-04-29 9:50

>>23
Good idea!
>>26
OP, this is vitally important
I don't think it is.
>>31
Go suck on a garden hose.
>>33
Oh. I see. Makes sense.

Name: 34 2009-04-29 11:37

It seems that this line:
const uint_fast8_t a = ((side == 0) ? LEFT : RIGHT);
will be compiled to this (-O0):
; line 11
        cmpb    $0, -10(%ebp)   ; (side == 0) ? ...
        jne     .L2
        movzbl  LEFT, %eax             
        movb    %al, -22(%ebp) ; ??? = LEFT
        jmp     .L3
.L2:
        movzbl  RIGHT, %eax            
        movb    %al, -22(%ebp) ; ??? = RIGHT
.L3:
        movzbl  -22(%ebp), %eax
        movb    %al, -7(%ebp)   ; a =  ???
; line 12

but an if statement like this:
    if(side == 0)
        c = LEFT;
    else
        c = RIGHT;

results in
; line 14-17
        cmpb    $0, -10(%ebp) ; if(side == 0)
        jne     .L6
        movzbl  LEFT, %eax
        movb    %al, -5(%ebp) ; c = LEFT
        jmp     .L7
.L6:
        movzbl  RIGHT, %eax
        movb    %al, -5(%ebp) ; c = RIGHT
.L7:
; line 18

How should I write my code to check if gcc will be able to optimize this? Would declaring a, c and side as volatile suffice?
Because I can't make heads or tails out of this code (-O2; a,b,side are declared volatile):
        movb    $0, -5(%ebp) ; side
        movb    $0, -6(%ebp) ; a
        movb    $0, -7(%ebp) ; c
        movzbl  -5(%ebp), %eax
        cmpb    $1, %al
        sbbl    %eax, %eax
        addl    $2, %eax
        movb    %al, -6(%ebp)
        movzbl  -5(%ebp), %eax
        testb   %al, %al
        je      .L8
        movb    $2, -7(%ebp)
        addl    $16, %esp
        xorl    %eax, %eax
        popl    %ecx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .p2align 4,,7
        .p2align 3
.L8:
        movb    $1, -7(%ebp)
        addl    $16, %esp

Name: Anonymous 2009-04-29 12:01

How about

a = 2 >> side;

?

Name: Anonymous 2010-11-27 1:10

Name: Anonymous 2010-12-17 1:24

Are you GAY?
Are you a NIGGER?
Are you a GAY NIGGER?

If you answered "Yes" to all of the above questions, then GNAA (GAY NIGGER ASSOCIATION OF AMERICA) might be exactly what you've been looking for!

Name: Anonymous 2011-02-03 5:53

Don't change these.
Name: Email:
Entire Thread Thread List