PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, April 27, 2022

[FIXED] how to disable this particular warning

 April 27, 2022     c, gcc, warnings     No comments   

Issue

This simple code:

#define WIDTH 500.5
#define NB 23.2

int x[(int)(WIDTH/NB)];

gives me a warning:

prog.c:4:1: warning: variably modified 'x' at file scope [enabled by default]

If I set #define WIDTH 500 and #define NB 23, the warning disappears.

Passing a float value for WIDTH macro forces evaluation by the compiler and thus issues a warning because array has not a constant size.

The preprocessed C code looks like int x[(int)(500.5/23.2)];, whereas int x[(int)(500/23)]; is OK for the compiler (value is already constant integer)

I would like to find a way either

  • to ignore this particular warning (but leaving the others so I can enable -Werror: seems that is a lost cause: GCC, C: Finding out name of default warnings for use in #pragma ignore
  • fix the code so it does what I want without issuing warnings.
  • force the pre-processor to perform the computation as integer

Funny thing: compiling with g++ I don't have the warning whereas I read here that variable length arrays are not officially supported in C++, only in C99. But that's not an option for me, since I need to stick to C.


Solution

One could ensure that a normal array (non VLA) is created like this:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
enum{ARRAY_DIMENSION_OF_x = (int)(WIDTH/NB)};
int x[ARRAY_DIMENSION_OF_x];
#pragma GCC diagnostic pop

This compiles without warning in gcc and clang in C mode and with a old-style cast to 'int' warning in C++ mode.

One could also hide the creation of the enum within a macro:

/* ================= define MAKE_CONST_INT() macro ================= */
#ifdef __cplusplus
     template<class T> struct make_const_int_helper{static T t;};
#    define MAKE_CONST_INT(x) (sizeof(*(make_const_int_helper<char (*)[int((x)+0L)]>::t)))  /* +0L avoids "useless cast" warning*/
#else
#    define EVALUATE_TO_0(type) (0*__builtin_types_compatible_p(type,int))
#    define EVALUATE_TO_0_PRAGMA(x) EVALUATE_TO_0(struct{int dummy; _Pragma(x)})

#    define EVALUATE_TO_0_START_DISABLE_WARNINGS                                \
        ( EVALUATE_TO_0_PRAGMA("GCC diagnostic push")                           \
        + EVALUATE_TO_0_PRAGMA("GCC diagnostic ignored \"-Wpedantic\"")         \
        + EVALUATE_TO_0_PRAGMA("GCC diagnostic ignored \"-Wc++-compat\"") )
#    define EVALUATE_TO_0_END_DISABLE_WARNINGS \
        EVALUATE_TO_0_PRAGMA("GCC diagnostic pop")

#    define MAKE_CONST_INT(x) MAKE_CONST_INT_HELPER2(x,__LINE__,__COUNTER__)
#    define MAKE_CONST_INT_HELPER2(x,line,counter) MAKE_CONST_INT_HELPER(x,line,counter)
#    define MAKE_CONST_INT_HELPER(x,line,counter)                                   \
        ( EVALUATE_TO_0_START_DISABLE_WARNINGS                                      \
        + EVALUATE_TO_0(enum{ INT_CONSTANT_##counter##_AT_LINE_##line = (int)(x) }) \
        + INT_CONSTANT_##counter##_AT_LINE_##line                                   \
        + EVALUATE_TO_0_END_DISABLE_WARNINGS)
#endif





/* ================= test MAKE_CONST_INT() macro ================= */
#define WIDTH 500.5
#define NB 23.2
extern int x[MAKE_CONST_INT(WIDTH/NB)];

This compiles without warning in gcc and clang in C and in C++ mode.

The structs with the int dummy members are only necessary to get a place where gcc accepts a _Pragma("GCC diagnostic ....") pragma.

Example


Extended implementation that works for MSVC, gcc, clang and icc, but still won't compile on really picky compilers:

/* ================= define MAKE_CONST_INT() macro ================= */
#ifdef __cplusplus
#    if defined(__GNUC__) && !defined(__clang__)
 #       pragma GCC diagnostic push
 #       pragma GCC diagnostic ignored "-Wtemplates"
#    endif
    template<class T> struct make_const_int_helper{static T t;};
#    if defined(__GNUC__) && !defined(__clang__)
 #       pragma GCC diagnostic pop
#    endif
#    define MAKE_CONST_INT(x) (sizeof(*(make_const_int_helper<char (*)[int((x)+0L)]>::t)))  /* +0L avoids "useless cast" warning*/
#else
#    if defined(__GNUC__)
#        define EVALUATE_TO_0(type) (0*__builtin_types_compatible_p(type,int))
#        define EVALUATE_TO_0_PRAGMA(x) EVALUATE_TO_0(struct{int dummy; _Pragma(x)})
#        define EVALUATE_TO_0_START_DISABLE_WARNINGS                                \
            ( EVALUATE_TO_0_PRAGMA("GCC diagnostic push")                           \
            + EVALUATE_TO_0_PRAGMA("GCC diagnostic ignored \"-Wpedantic\"")         \
            + EVALUATE_TO_0_PRAGMA("GCC diagnostic ignored \"-Wc++-compat\"") )
#        define EVALUATE_TO_0_END_DISABLE_WARNINGS \
            EVALUATE_TO_0_PRAGMA("GCC diagnostic pop")                       
#    else
#        define EVALUATE_TO_0(type) (0*sizeof(type))
#        if defined(_MSC_VER)
#            define EVALUATE_TO_0_START_DISABLE_WARNINGS \
                (0 __pragma(warning( push )) __pragma(warning(disable:4116)))
#            define EVALUATE_TO_0_END_DISABLE_WARNINGS (0 __pragma(warning( pop )) )
#        else
#            define EVALUATE_TO_0_START_DISABLE_WARNINGS 0  /*other compilers will not disable warning*/
#            define EVALUATE_TO_0_END_DISABLE_WARNINGS 0
#        endif
#    endif
#    define MAKE_CONST_INT(x) MAKE_CONST_INT_HELPER2(x,__LINE__,__COUNTER__)
#    define MAKE_CONST_INT_HELPER2(x,line,counter) MAKE_CONST_INT_HELPER(x,line,counter)
#    define MAKE_CONST_INT_HELPER(x,line,counter)                                   \
        ( EVALUATE_TO_0_START_DISABLE_WARNINGS                                      \
        + EVALUATE_TO_0(enum{ INT_CONSTANT_##counter##_AT_LINE_##line = (int)(x) }) \
        + INT_CONSTANT_##counter##_AT_LINE_##line                                   \
        + EVALUATE_TO_0_END_DISABLE_WARNINGS)
#endif



/* ================= test MAKE_CONST_INT() macro ================= */
#define WIDTH 500.5
#define NB 23.2
extern int x[MAKE_CONST_INT(WIDTH/NB)];


Answered By - T S
Answer Checked By - Cary Denson (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home
View mobile version

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing