Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
177 views
in Technique[技术] by (71.8m points)

c - literal-conversion warning in union of structs

I try to wrap multiple structs in an union and access the structure using the macro SET. This macro sets the structure's field based on the given type t, which is an enum constant.

When I compile the below code with clang 12.0.0 I see the following -Wliteral-conversion warning:

union.c:46:19: warning: implicit conversion from 'float' to 'int' changes value from 1.3 to 1 [-Wliteral-conversion]
        SET (num, FLOAT, 1.3f);
        ~~~~~~~~~~~~~~~~~^~~~~
union.c:31:14: note: expanded from macro 'SET'
                u.ni.val = v;                           
                     ~ ^

This behaviour occurs whenever I call SET with float values, for example,

SET (num, FLOAT, 1.3f);

However, the code compiles without warning when I write the switch block from the definition of SET to the main function.

What am I doing wrong here?

/* Compile with:
 * cc -Wall -std=c17
 */
#include <stdio.h>

enum numer_type { VOID, INT, FLOAT };

union Number {
    struct {
        int type;
    } n;
    
    struct {
        int type;
        int val;
    } ni;

    struct {
        int type;
        float val;
    } nf;
};

#define SET(u, t, v) switch (t) {   
    case VOID:                      
        u.n.type = t;               
        break;                      
                                    
    case INT:                       
        u.ni.type = t;              
        u.ni.val = v;               
        break;                      
                                    
    case FLOAT:                     
        u.nf.type = t;              
        u.nf.val = v;               
        break;                      
                                    
    default:                        
        puts ("Unknown");           
}

int main (void)
{
    union Number num;
    SET (num, FLOAT, 1.3f);

    return 0;
}
question from:https://stackoverflow.com/questions/66065324/literal-conversion-warning-in-union-of-structs

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In the code resulting from the expansion of SET(num, FLOAT, 1.3), the line u.ni.val = v; in the INT case assigns a double literal 1.3 to the int member u.ni.val. Although this code is never executed due to the switch on t, the compiler does not know this and issues a warning.

You could avoid the warning by changing the assignment to u.ni.val = (int) v;.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...