2

(My question is mostly the same as this one, but my needs are different, hence I need a different solution.)

I am attempting to use test-driven development, and am writing a set of tests to validate the behavior of my BIT(n) macro:

#define BIT(n) ( ((uint64_t)1) << (n) )

Since my test for the above includes both expected-pass and expected-fail components, I intentionally do bad things such as

MY_TEST_ASSERT(0 == (value64 = BIT(65)));

which, if there was a problem with my implementation if BIT(n), would output something helpful like

TEST FAILED: '0 == (value64 = BIT(65))' (file 'tests/002.bit-hackery.cpp', line 12))

Everything works as expected, but I get an annoying warning during compilation:

../../inc/bit-hackery.hpp:15:32: warning: left shift count >= width of type [enabled by default]

(It is actually annoying for two reasons: (1) I want it suppressed for this test code, since I am testing this situation on purpose, and (2) in real (non-test) code, I would rather it be treated as an error. But, this question is about the former.)

I've tried suppressing it with a #pragma directive, but I can't seem to find one that works:

#pragma GCC diagnostic push
//#pragma GCC diagnostic ignored "-Wcomparison-fixed"
//#pragma GCC diagnostic ignored "-Wtype-limits"
//#pragma GCC diagnostic ignored "-Wextra"
//#pragma GCC diagnostic ignored "-Wall"
  MY_TEST_ASSERT(0 != (value64 = BIT(65)));
#pragma GCC diagnostic pop

Does anyone know how to suppress this particular warning?

My compiler version is g++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4

Community
  • 1
  • 1
Cognitive Hazard
  • 1,072
  • 10
  • 25
  • 1
    it's worth pointing out that shifting by the width of the operand is *undefined behavior*. It's not implementation defined. This code tests the *compiler*, nothing else. It invokes undefined behavior and it makes assumptions about what the compiler does about it. I don't think it's reasonable for unit tests to contain invalid C++ code. – Arvid May 15 '16 at 00:33

2 Answers2

1

Unfortunately g++ v4.8.x hasn't a flag to disable that particular warning.

You can instructs GCC/G++ to indicate which command line option directly controls each diagnostic emitted (if such an option is known to the diagnostic system) via the -fdiagnostics-show-option flag.

In the specific case no -W option is indicated.

For newer versions of G++/CLANG++ you've the -Wshift-count-overflow flag.

I don't think there's a way to disable all g++ warnings on a few line of code (e.g. How to disable all warnings in g++ on a few lines of code).

The -w flag will disable all warnings on the whole file but it's excessive.


PS the inline-function version of BIT doesn't trigger the warning:

std::uint64_t BIT(std::uint64_t n) { return UINT64_C(1) << n; }
Community
  • 1
  • 1
manlio
  • 18,345
  • 14
  • 76
  • 126
  • Thanks, and I appreciate the tip about inlining to avoid this. – Cognitive Hazard Feb 16 '16 at 03:33
  • ... although, at least with this compiler, the inline version yields incorrect results for BIT(65) when compiling with -O0 (for debug builds) instead of -O2... whereas the macro version is consistently correct. – Cognitive Hazard Feb 16 '16 at 05:39
1

One way to avoid a compile time warning is to first assign your number 65 to a variable and then pass the variable to the macro instead. This hides the issue from the compiler, making it a run time problem, which is what you want. In fact, you should probably do this for all your test cases anyway because compilers can choose to simplify the resulting code for macros and inline functions when constants are passed.

PaulRuby
  • 11
  • 1