How to mark an unused parameter of constexpr function?

Consider this classic example:

template <typename T, std::size_t N> constexpr std::size_t arraySize(T (&array)[N]) noexcept { return N; } 

Now this works fine, but there is one annoyance, gcc gives a warning:

 warning: unused parameter 'array' [-Wunused-parameter] 

Known solutions:

  • Doesn't work: if I add the classic (void)arr; to the function, I get error: body of constexpr function '...' not a return-statement .
  • Unsatisfactory: I may have arraySize(T (&)[N]) , but I want to name the argument for two reasons:
    • This makes the compiler error message more understandable.
    • More subjectively, I think that it makes the code more understandable, especially to those who do not live and breathe this syntax.
  • Not good: in this particular example, I could also return sizeof(array)/sizeof(array[0]); , but this approach is not a universal solution, and I also think that return N; much nicer, definitely easier on the eye.
  • Good, but not always possible: switch to using C ++ 14 and a compiler that fully supports it. Then the body of the constexpr function, like { (void)array; return N; } { (void)array; return N; } { (void)array; return N; } .

How can I get rid of warning of unused parameters when using C ++ 11 ?

+5
source share
7 answers

I would suggest the following (ab) using a comma operator:

 return (void)array, N; 
+4
source

Try it. I sometimes use this method

 template <typename T, std::size_t N> constexpr std::size_t arraySize(T (& /*array*/ )[N]) noexcept { return N; } 
+4
source

The best solution is one that is prohibited by the second point, that is, use T(&)[N] .

Another possible approach, as from the comment, is to use the following return value:

 return array ? N : N; 

I am sure that the compiler will get rid of it, and there will be no performance problems at runtime.

+2
source

For new googlers:

C ++ 17 adds the [[maybe_unused]] attribute, which can be used as follows:

 template <typename T, std::size_t N> constexpr std::size_t arraySize(T (&array)[N] [[maybe_unused]]) noexcept { return N; } 
+2
source

As @ fnc12 and @skypjack note, the idiomatic way to silence a warning about an unused compiler parameter is to not specify the name of this parameter.

 constexpr std::size_t arraySize(T (& /*array*/ )[N]) noexcept { return N; } 

The use of comments /**/ allows for the objection of readability. It does not capture the name in the compiler message, but I would say that the most probable situation arising from this is the “undeclared identifier”, which is quite easy and obvious to solve after you notice that the identifier is commented out.

If you are really dead in relation to the idiomatic path, just suppress the warning (locally if your compiler allows it).

GCC warning suppression using #pragma GCC diagnostic .

Visual Studio #pragma warning suppress with #pragma warning suppress

I recommend not adding "dummy" code links in order to shut down the compiler. A link to an unused parameter for any reason other than to warn about the compiler, uselessly adds complexity to your code and may confuse future maintainers why it is there.

+1
source

An unnamed argument is the correct solution.

So you can use an intermediate function:

 template <typename T> constexpr void avoid_warning_for_unused_parameter(T&&) noexcept{} 

and then:

 template <typename T, std::size_t N> constexpr std::size_t arraySize(T (&array)[N]) noexcept { avoid_warning_for_unused_parameter(array); return N; } 

For C ++ 11 you need to hack a bit:

 template <typename... Ts> constexpr auto return_first_and_avoid_warning_for_unused_parameters(T&&t, Ts&&) noexcept -> decltype(t) { return t; } template <typename T, std::size_t N> constexpr std::size_t arraySize(T (&array)[N]) noexcept { return return_first_and_avoid_warning_for_unused_parameters(N, array); } 
+1
source

gcc provides an unused attribute that can be used as follows:

 constexpr std::size_t arraySize(__attribute__((unused)) T (&array)[N]) noexcept { return N; } ^^^^^^^^^^^^^^^^^^^^^^^ 

Ben Dane recently made friends with the C ++ 11 way to suppress this warning using lambdas, which in combination with the comma operator would look something like this

 #define UNUSED(x) [&x]{}() //... return UNUSED(array), N; 
+1
source

Source: https://habr.com/ru/post/1234460/


All Articles