skip to Main Content

Please see the code example below

  1. Does anyone know why visual studio 22 behaves this way
  2. Does anyone know if there is a setting or something i can change to my debug configuration so that it does not generate the ‘not all paths return a value’ warning

Note: I have ‘treat warnings as errors’ – this cannot change

// In debug this compiles
// In release this has a compiler warning about unreachable code
int aaa()
{
  int value = 0;
  try
  {
    value = myFunctionThatCouldThrow();
  }
  catch (const std::exception& exc)
  {
    ThisFunctionALWAYSThrows(exc);
  }
  return value;
}

// In debug this has a compiler warning that not all paths return a value
// In release this compiles
int aaa()
{
  try
  {
    return myFunctionThatCouldThrow();
  }
  catch (const std::exception& exc)
  {
    ThisFunctionALWAYSThrows(exc);
  }
}

// This compiles in both but requires the preprocessor debug flag
int aaa()
{
  try
  {
    return myFunctionThatCouldThrow();
  }
  catch (const std::exception& exc)
  {
    ThisFunctionALWAYSThrows(exc);
  }
#ifdef _DEBUG
  // The return statement is a pointless line as it can never be hit - I agree with the release build warning
  // yet without this return statement - code building in debug generates a warning...
  // I know I could also pragma ignore the warning - Im hoping for a cleaner solution without macros
  // There are multiple functions in the code base that behave this way (the codes been ported from VS17)
  // A non macro solution is better as I dont need to amend all functions
  // I also dont want a more global ignore of the warning as that could hide genuine issues
  return -1;
#endif
}

2

Answers


  1. Chosen as BEST ANSWER

    First up apologies - my initial code was not going to reproduce the issue - it was copied from code i couldnt share as an example. Its amended now. The questions posted did assist me in spotting this oversight and working out the error. Thankyou.

    Onto the answer - its just due to the optimiser. The function that always throws is optimised to be an inline throw meaning release wont complain about all paths not returning a value. Whereas debug it wont optimise and it will complain.


  2. First thing I need to mention that I couldn’t reproduce your warnings in Compiler Explorer with any available MSVC compilers. Try providing reproducible example.
    Assuming that the warning really exists, you can disable it with #pragma warning(disable: 4702), where 4702 is the unreachable code warning.
    Notice, that when using warnings with numbers 4700-4999 a special rule exists. Quoting from Microsoft documentation: (https://learn.microsoft.com/en-us/cpp/preprocessor/warning?view=msvc-170)

    Warning numbers in the range 4700-4999 are associated with code
    generation. For these warnings, the state of the warning in effect
    when the compiler reaches the function definition remains in effect
    for the rest of the function. Use of the warning pragma in the
    function to change the state of a warning number larger than 4699 only
    takes effect after the end of the function.

    In your case it would look like this:

    #pragma warning(push)
    #pragma warning(disable: 4702)
    // In debug this compiles
    // In release this has a compiler warning about unreachable code
    int aaa()
    {
      int value = 0;
      try
      {
        value = myFunctionThatCouldThrow();
      }
      catch (const std::exception& exc)
      {
        std::stringstream ss;
        ss << "my function threw: " << exc.what();
        throw std::runtime_error(ss.str().c_str());
      }
      return value;
      #pragma warning(pop)
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search