1

I compiled my code with the same version of GCC using both -std=gnu++17 and -std=gnu++20. This warning appears for c++17 but is NOT present when using c++20.


I am going to state right up front that, try as I might, I have been unable to create a minimum reproducible example of this problem, but I will continue to try. In the absence of an example, I am just looking for some guidance or would like to know if anyone has ever encountered a similar problem.


I am encountering a large number of the following warnings in my code:

left shift of negative value [-Wshift-negative-value]

The odd thing is, the place where the error is occurring is on the following lines which occur all over my code (as part of a state machine framework):

CState(static_cast<CState::State>(...))

Where CState and State are:

class CState {
public:
    using State = CState (AbstractStateMachineV2::*)(const AbstractEventV2&);
    
    constexpr CState(State fn = nullptr) : _fn(fn) {}
    static constexpr CState null() { return CState(); }
    
    inline CState operator()(AbstractStateMachineV2& context, const AbstractEventV2& e) {
        return context.call(_fn, e);
    }
    
    inline operator bool() const { return _fn != nullptr; }
    inline bool operator==(CState const& other) { return _fn == other._fn;}
    inline bool operator!=(CState const& other) { return _fn != other._fn;}

private:
    State _fn;
};

Where the value being casted is just a pointer to a member method used like so:

class MyStateMachine : public AbstractStateMachineV2
{
protected:
    CState myState(const AbstractEventV2& e);
};

auto s = CState(static_cast<CState::State>(&MyStateMachine::myState));

As you can see, there is no shifting being done here. And none of the other code that I didn't show involves shifting either.

Unfortunately, I can provide no further insight than this.

I am using the following GCC version but also get the same results on the latest version:

arm-none-eabi-g++.exe (GNU Tools for STM32 10.3-2021.10.20211105-1100) 10.3.1 20210824 (release)

I would really appreciate even the smallest bit of insight anyone could provide on this.

I don't know if this will help at all, but here is a snippet of the actual compilation output for a single source file of my project:

arm-none-eabi-g++ -g3 --specs=nano.specs -mfpu=fpv5-sp-d16 -mfloat-abi=hard -O1 -Wno-missing-field-initializers --debug -g -DBUILD_VERSION_RELEASE=0 -DBUILD_VERSION_MAJOR=0 -DBUILD_VERSION_MINOR=0 -DBUILD_VERSION_BUILD=0 -DBUILD_VERSION_STEM="'a'" -DBUILD_VERSION=\"\" -DUNIX_TIMESTAMP_COMPILE_DATE=\""NO-COMPILE-TIME-PROVIDED"\" -DCOMPILE_BRANCH=\""no-branch"\" -DCODE_REVISION=\""0000000000000000000000000000000000000000"\" -DCODE_REVISION_HASH="{"0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00"}" -DPROJECT_NAME=\"prj-tw-av-base\" -DBUILD_CONFIGURATION=\"debug\" -DBUILD_TARGET_ARCH=\"stm32l562xx\" -DNULL=0 -DDEBUG=1 -DHAVE_CONFIG_H -DOPUS_ARM_ASM -DTW_DEBUG=1 -DLFS_THREADSAFE=1 -DUSE_HAL_DRIVER -DSTM32L562xx -DUSE_FULL_LL_DRIVER -fdata-sections -ffunction-sections -fstack-usage -mcpu=cortex-m33 -MMD -MP -mthumb -Wall -Wextra -mfpu=fpv5-sp-d16 -mfloat-abi=hard -c  -std=gnu++17 -fno-exceptions -fno-rtti -fno-use-cxa-atexit -Wdelete-non-virtual-dtor -Wno-volatile -Ilibraries/lib-ext-ctti/include/ -Ilibraries/lib-ext-etl/include/ -Ilibraries/lib-gsp-core-framework/include/ -Ilibraries/lib-tw-av-base-littlefs/include/ -Isources/prj-tw-av-base/include -Isources/prj-tw-av-base/private-include -Itwframework/include -Itwstm32/include -Itwcommon/include -Itwstm32/freertos/include -Itwstm32/stm32cube/STM32L5xx_HAL_Driver/Inc -Itwstm32/stm32cube/CMSIS/Device/ST/STM32L5xx/Include -Itwstm32/stm32cube/CMSIS/Include -Itwstm32/freertos/portable/GCC/ARM_CM33_NTZ/non_secure -Iavbase/include -Iconfig/include -Itwinnet/include -Ist8500/include -Itwfreertos/include -Itwstm32/stm32cube/STM32L5xx_HAL_Driver/Inc/Legacy -Iseggersystemview/include -Iopus/include -Iopus/silk -Iopus/celt -Iopus -Iopus/silk/fixed -Iopus/silk/arm -Iopus/silk/fixed/arm -Iopus/celt/arm -o "build/stm32l562xx/debug/obj/./avbase/src/tw/avbase/filesystem/FilesystemSubsystem.cpp.obj" "avbase/src/tw/avbase/filesystem/FilesystemSubsystem.cpp"
In file included from twframework/include/tw/statemachinev2/StateMachine.h:10,
                 from avbase/include/tw/avbase/filesystem/FilesystemSubsystem.h:26,
                 from avbase/src/tw/avbase/filesystem/FilesystemSubsystem.cpp:10:
avbase/include/tw/avbase/filesystem/FilesystemSubsystem.h: In static member function 'static constexpr tw::AbstractStateMachineV2::CState tw::avbase::FilesystemSubsystem::sFS_INFO::init()':
twframework/include/tw/statemachinev2/macros.h:31:89: warning: left shift of negative value [-Wshift-negative-value]
   31 |         static constexpr CState init() { return CState(static_cast<CState::State>(&init_)); }\
      |                                                                                         ^
twframework/include/tw/statemachinev2/macros.h:19:50: note: in expansion of macro '_TW_DECLARE_STATE3'
   19 | #define _TW_DECLARE_STATEN(_1, _2, _3, FN_, ...) FN_
      |                                                  ^~~
twframework/include/tw/statemachinev2/macros.h:18:31: note: in expansion of macro '_TW_DECLARE_STATEN'
   18 | #define TW_DECLARE_STATE(...) _TW_DECLARE_STATEN(__VA_ARGS__, _TW_DECLARE_STATE3, _TW_DECLARE_STATE2, _TW_DECLARE_STATE1)(__VA_ARGS__)
      |                               ^~~~~~~~~~~~~~~~~~
avbase/include/tw/avbase/filesystem/FilesystemSubsystem.h:77:2: note: in expansion of macro 'TW_DECLARE_STATE'
   77 |  TW_DECLARE_STATE(sFS, FilesystemSubsystem::top, FilesystemSubsystem::sFSIdle);
      |  ^~~~~~~~~~~~~~~~
avbase/src/tw/avbase/filesystem/FilesystemSubsystem.cpp: In constructor 'tw::avbase::FilesystemSubsystem::FilesystemSubsystem(tw::AbstractActiveThread&, tw::twfs::AbstractFilesystem&, tw::twinnet::app::MessageRouter&, tw::twinnet::app::SubAddress, const char*, tw::logging::AbstractLoggable*)':
twframework/include/tw/statemachinev2/macros.h:161:54: warning: left shift of negative value [-Wshift-negative-value]
  161 |  transition(CState(static_cast<CState::State>(&state_)))
      |                                                      ^
avbase/src/tw/avbase/filesystem/FilesystemSubsystem.cpp:39:2: note: in expansion of macro 'TW_INITIAL_TRANSITION'
   39 |  TW_INITIAL_TRANSITION(FilesystemSubsystem::sFS);
      |  ^~~~~~~~~~~~~~~~~~~~~
...

Every time I do that function pointer casting (via a helper macro), a warning is generated.

The warning is even generated if I add a line as simple as:

FilesystemSubsystem::FilesystemSubsystem()
{
    //Warning generated at the following line
    auto s = CState(static_cast<CState::State>(&FilesystemSubsystem::state1));
}

AbstractStateMachineV2::CState FilesystemSubsystem::state1(const AbstractEventV2& _e)
{
    //...
}

This makes me start to wonder if there is some sort of really odd compiler bug that is exhibiting itself.

Patrick Wright
  • 1,401
  • 7
  • 13
  • Look for complements (`~`), too, and values smaller than `int` (and in casts)). Is your code the **only** code being compiled during make? – Dave Newton Jan 25 '23 at 18:01
  • Does this have any bearing? [comparing pointer to a negative value](https://stackoverflow.com/questions/19139258/comparing-pointer-to-a-negative-value) – Dúthomhas Jan 25 '23 at 18:29
  • @Dúthomhas After reading the article, I don't believe this is the issue. Literally the only cast I am ever doing is what I showed. It is a cast from a method pointer to a concrete type to a pointer of an abstract type. – Patrick Wright Jan 25 '23 at 20:19
  • It's happening in a constructor. Even a user-defined constructor has a bunch of compiler-generated logic to initialize all subobjects (base classes and member variables). I think the warnings are coming from member variables' brace-or-equal-initializer expressions, that in the source code are inline in the class definition, but actually result in code generation in the constructor. – Ben Voigt Jan 25 '23 at 21:37

0 Answers0