gracicot / kangaru

🦘 A dependency injection container for C++11, C++14 and later
MIT License
489 stars 39 forks source link

Unreachable code warning (C4702) triggered when injecting service dependency in MSVC #119

Open WopsS opened 8 months ago

WopsS commented 8 months ago

Describe the bug When attempting to inject a service dependency into another service within a C++ project using MSVC compiler, the compiler generates a warning C4702: unreachable code during compilation. This warning occurs specifically in virtual_injected class.

https://github.com/gracicot/kangaru/blob/329989aa57210fb9c883ccabc1db666f6b70c34d/include/kangaru/detail/injected.hpp#L59

To Reproduce

  1. Create CMakeLists.txt with the following content:
    
    cmake_minimum_required(VERSION 3.21)

include(FetchContent)

project( kangaru-c4702-unreachable-code LANGUAGES CXX ) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CONFIGURATION_TYPES "Release")

option(KANGARU_REVERSE_DESTRUCTION "" ON)

FetchContent_Declare( kangaru GIT_REPOSITORY https://github.com/gracicot/kangaru.git GIT_TAG 329989aa57210fb9c883ccabc1db666f6b70c34d ) FetchContent_MakeAvailable(kangaru)

add_compile_options(/W4 /WX)

add_executable(${PROJECT_NAME} Main.cpp) target_link_libraries(${PROJECT_NAME} PRIVATE kangaru::kangaru)

2. Create the `Main.cpp` file with the following content:
```cpp
#include <kangaru/kangaru.hpp>

class Fuel
{
public:
    Fuel() = default;
    virtual ~Fuel() = default;
};

struct FuelService : kgr::abstract_service<Fuel>
{
};

class Car
{
public:
    Car(const Fuel& fuel)
        : m_fuel{fuel}
    {
    }

    virtual ~Car() = default;

private:
    const Fuel& m_fuel;
};

class Toyota : public Car
{
public:
    Toyota(const Fuel& fuel) // This line cause the warning.
        : Car{fuel}
    {
    }

    ~Toyota() final = default;
};

struct ToyotaService
    : kgr::single_service<Toyota, kgr::dependency<FuelService>>
{
};

int main()
{
    kgr::container m_services;
    m_services.emplace<ToyotaService>();
    return 0;
}
  1. Compile it in Release.

Expected behavior The code should compile without triggering any warnings related to unreachable code (warning C4702).

Desktop (please complete the following information):

Additional context I tried to figure out if the problem is with kangaru or MSVC, but couldn't recreate it with a similar class as virtual_injected. I assume it might be because of the optimization in Release.

It would be great if you could have a look at it to determine if this is really from kangaru or MSVC, or between the chair and the keyboard.

gracicot commented 8 months ago

Thank you for the report, I'll take a look!

gracicot commented 8 months ago

After looking at it, I can say that I'm almost certain this is a false positive. I would report this to the MSVC team. Those function does not throw and does not use control flow. I cannot see how those could have unreachable code.

I also noticed injected from injected.hpp also show this issue there: https://github.com/gracicot/kangaru/blob/f66a8049ffaece44c5a47b0b8bcff0c06742e548/include/kangaru/detail/injected.hpp#L27

The workaround would be to compile with kangaru as a system header (I don't think MSVC supports this) or to compile without /WX or with /W3 instead of /W4.

WopsS commented 8 months ago

Thank you for investigating! I'll go ahead report it to the MSVC team.

WopsS commented 8 months ago

I have reported the issue on Developer Community. If you would like to follow it, here is the link: https://developercommunity.visualstudio.com/t/Unreachable-code-warning-C4702-trigger/10582835

Since this is a false positive, feel free to close this issue.

gracicot commented 8 months ago

Thanks for the link! I'll keep this issue around until we get a response from microsoft's MSVC team.