Home > Software design >  using a const static array in constructor result in 'warning ... is used uninitialized in this
using a const static array in constructor result in 'warning ... is used uninitialized in this

Time:10-17

I am trying to understand a compiler warning. I have a simple class

#pragma once

#include <framework/project_definitions.hpp>
#include <framework/free_rtos/free_rtos.hpp>
#include <modules/net/imqtt_client.hpp>
#include "mqtt_command_base.hpp"

namespace application::commands
{
    class check_alive_command : public mqtt_command_base
    {
    public:
        check_alive_command(
            modules::imqtt_client &mqtt_client,
            framework::free_rtos::ifree_rtos &free_rtos);

        int32_t execute(const uint8_t *payload, uint32_t length) override;
    };
}

with the following implementation

#include "check_alive_command.hpp"

const static uint8_t _payload_buffer[10] = {};

namespace application::commands
{    
    check_alive_command::check_alive_command(
        modules::imqtt_client &mqtt_client,
        framework::free_rtos::ifree_rtos &free_rtos) :
            mqtt_command_base(
                mqtt_client,
                free_rtos,
                iobox_check_alive_command,
                stack_size_small,
                &_payload_buffer[0])
    {
    }

    int32_t check_alive_command::execute(const uint8_t *payload, uint32_t length)
    {
        return modules::mqtt_error_code::ok;
    }
}

The base of check_alive_command

#pragma once

#include <modules/net/imqtt_client.hpp>
#include <framework/free_rtos/free_rtos.hpp>

namespace valinso::application::commands
{
    class mqtt_command_base
    {
    public:
        mqtt_command_base(
            modules::imqtt_client &mqtt_client, 
            framework::free_rtos::ifree_rtos &free_rtos,
            const char * command_name,
            const uint32_t stack_size,
            uint8_t *payload_buffer);

        void run(const uint8_t *payload, uint32_t length);
        virtual int32_t execute(const uint8_t *payload, uint32_t length) = 0;

    protected:
        modules::imqtt_client &_mqtt_client;
        framework::free_rtos::ifree_rtos &_free_rtos;

        const char * _command_name;
        const uint32_t _stack_size;

        uint8_t *_payload_buffer;
        size_t _current_payload_length = 0;

        bool _is_busy = false;
    };
}

The compiler warns

/home/bp/dev/iobox/firmware/app/iobox/commands/check_alive_command.cpp: In constructor 'application::commands::check_alive_command::check_alive_command(modules::imqtt_client&, framework::free_rtos::ifree_rtos&)':
/home/bp/dev/iobox/firmware/app/iobox/commands/check_alive_command.cpp:15:18: warning: '*<unknown>.application::commands::check_alive_command::<anonymous>.application::commands::mqtt_command_base::_payload_buffer' is used uninitialized in this function [-Wuninitialized]
   15 |                 &_payload_buffer[0])

Why? How?? It's not even true, right? Startup code which initialized .data section, runs before my __libc__init_array. So why would this be uninitialized? More importantly, how can I fix this warning? Personally more important: why does it give this warning?

CodePudding user response:

It's simple, really. You have two variables named _payload_buffer. One is your static constant, and the other one is one of mqtt_command_base's members.

When you refer to _payload_buffer in check_alive_command's constructor, you're really using the member, not the static variable. So of course, it is uninitialized at this time. Your compiler is right.

As for the fix, either rename one of those two, or tell the compiler you want the global one with :::

mqtt_command_base(
            mqtt_client,
            free_rtos,
            iobox_check_alive_command,
            stack_size_small,
            &::_payload_buffer[0]) // <-- :: right there

It's up to you.

  •  Tags:  
  • c
  • Related