0

I have following problem. I have defined C++ class called Mux

class Mux{
public:
    Mux(uint32_t* const bitsArray, const uint32_t control_01, const uint32_t control_02,
        float* input_01, float* input_02, float* input_03, float* input_04,
        float* output);
    virtual ~Mux();

    void Update(void);

private:

    uint32_t* m_BitsArray;
    uint32_t  m_Control01;
    uint32_t  m_Control02;
    float*    m_Input01;
    float*    m_Input02;
    float*    m_Input03;
    float*    m_Input04;
    float*    m_Output;

    uint8_t GetControlValue(uint32_t* const bitsArray, const uint32_t control_01, const uint32_t control_02);

};

Mux::Mux(uint32_t* const bitsArray,
                        const uint32_t control_01, const uint32_t control_02,
                        float* input_01, float* input_02, float* input_03, float* input_04,
                        float* output):
                        m_BitsArray{bitsArray},
                        m_Control01{control_01},
                        m_Control02{control_02},
                        m_Input01{input_01},
                        m_Input02{input_02},
                        m_Input03{input_03},
                        m_Input04{input_04},
                        m_Output{output}{

}

Mux::~Mux() {
    // TODO Auto-generated destructor stub
}

void Mux::Update(void){

    uint8_t controlValue = GetControlValue(m_BitsArray, m_Control01, m_Control02);

    switch(controlValue){

        case 0:
            *m_Output = *m_Input01;
        break;

        case 1:
            *m_Output = *m_Input02;
        break;

        case 2:
            *m_Output = *m_Input03;
        break;

        case 3:
            *m_Output = *m_Input04;
        break;

    }

}

uint8_t Mux::GetControlValue(uint32_t* const bitsArray, const uint32_t control_01, const uint32_t control_02){

    uint8_t controlValue = 0;

    if(Utils::TestBitSet(bitsArray, control_01)){
        controlValue += 1;
    }

    if(Utils::TestBitSet(bitsArray, control_02)){
        controlValue += 2;
    }

    return controlValue;

}

As soon as I attempt to instantiate this class in another class called Test I receive error: invalid conversion from 'const float*' to 'float*' [-fpermissive] in compilation process and last argument in Mux class constructor call in Test constructor is underlined.

class Test{
public:

    Test(float par01Value, float par02Value);
    virtual ~Test();

    void Loop(void);

private:

    uint32_t m_BitsArray[1] = {0};

    Mux *m_MuxTest;

    const float m_ErrVal = 0.0;

    struct Pars_t{
        float par01;
        float par02;
    };

    struct Vars_t{
        float var01;
        float var02;
        float var03;
    };

    Vars_t m_Vars = {0.0};
    Pars_t m_Pars = {0.0};

};



#define LW_01               (0)

// Byte 01
#define LSig01              (LW_01*32 + 0x00)
#define LSig02              (LW_01*32 + 0x01)
//efine L                   (LW_01*32 + 0x02)
//efine L                   (LW_01*32 + 0x03)
//efine L                   (LW_01*32 + 0x04)
//efine L                   (LW_01*32 + 0x05)
//efine L                   (LW_01*32 + 0x06)
//efine L                   (LW_01*32 + 0x07)

// Byte 02
//efine L                   (LW_01*32 + 0x08)
//efine L                   (LW_01*32 + 0x09)
//efine L                   (LW_01*32 + 0x0A)
//efine L                   (LW_01*32 + 0x0B)
//efine L                   (LW_01*32 + 0x0C)
//efine L                   (LW_01*32 + 0x0D)
//efine L                   (LW_01*32 + 0x0E)
//efine L                   (LW_01*32 + 0x0F)

// Byte 03
//efine L                   (LW_01*32 + 0x10)
//efine L                   (LW_01*32 + 0x11)
//efine L                   (LW_01*32 + 0x12)
//efine L                   (LW_01*32 + 0x13)
//efine L                   (LW_01*32 + 0x14)
//efine L                   (LW_01*32 + 0x15)
//efine L                   (LW_01*32 + 0x16)
//efine L                   (LW_01*32 + 0x17)

// Byte 04
//efine L                   (LW_01*32 + 0x18)
//efine L                   (LW_01*32 + 0x19)
//efine L                   (LW_01*32 + 0x1A)
//efine L                   (LW_01*32 + 0x1B)
//efine L                   (LW_01*32 + 0x1C)
//efine L                   (LW_01*32 + 0x1D)
//efine L                   (LW_01*32 + 0x1E)
//efine L                   (LW_01*32 + 0x1F)

Test::Test(float par01Value, float par02Value){

    m_Pars.par01 = par01Value;
    m_Pars.par02 = par02Value;

    m_MuxTest = new Mux(m_BitsArray, LSig01, LSig02,
                                            &m_ErrVal,
                                            &(m_Pars.par01),
                                            &(m_Pars.par02),
                                            &m_ErrVal,
                                            &(m_Vars.var01));

}

void Test::Loop(void){

    m_MuxTest->Update();

}

Test::~Test(){
    // TODO Auto-generated destructor stub
}

}

I don't understand what I am doing wrong. Can anybody help?

L3sek
  • 211
  • 3
  • 8
  • Why are you passing pointers to the input floats? Why not pass the input floats by value? Why not pass the output float by reference (to avoid pointers). – Martin York Jul 24 '19 at 13:58

1 Answers1

-1

You declared m_ErrVal as a const float so &m_ErrVal is a const float *. The constructor of Mux expects a float * not a const float *. This is the error.

If you really want to do this, you will have to use const_cast.

For example const_cast<float*>(&m_ErrVal). Or you can remove the const qualifier if not needed, it is yours to choose.


EDIT: But if you do not intend to modify the given float * to the Mux constructor, I think you should pass them as const float * instead of using const_cast.

For more information about the use of const_cast, you can read @MaxLanghof comment or check this link.

Fareanor
  • 5,900
  • 2
  • 11
  • 37
  • Is something wrong ? Why the downvote ? Any explanation ? I would be glad to read it. – Fareanor Jul 24 '19 at 11:21
  • 2
    Neither of those is the correct choice. `m_Errval` is clearly not intended to be modified (and modifying it after a `const_cast` would be Undefined Behavior). The correct choice would be to make `m_Input01` a `const float*` (and make the constructor take a `const float*` because the input should not be modified. (Wasn't me who voted btw). – Max Langhof Jul 24 '19 at 11:22
  • @MaxLanghof Ah I see. Am I correct if I say that he should pass `const float *` into `Mux` constructor instead of `float *` (since he's not modifying the parameters) ? – Fareanor Jul 24 '19 at 11:24
  • @MaxLanghof Thanks for the explanation, I've cited it in my edit. – Fareanor Jul 24 '19 at 11:36
  • The use of `const_cast<>()` to remove a const qualifier is one of the biggest red flags in a code review. The result of this operation leads to very brittle code that can at some subsequent point easily lead to broken code because of the potential for causing undefined behavior. As a result I consider the advice `If you really want to do this, you will have to use const_cast.` so bad as to be wrong. – Martin York Jul 24 '19 at 13:52
  • @MartinYork Yes this is why I specified _"If you really want to do this"_ that is to say: _"if you really want to give a `const float *` to a `float *`"_. I agree, it is a bad idea, but without refactoring, `const_cast` is the only solution. And he seems to not modify the parameters so since he's not modifying them, `const_cast` should still be fine. Undefined behaviour occurs when we try to modify the resulting value. – Fareanor Jul 25 '19 at 06:39