0

I have read in this that in C it must be safe (based on the answers)

And I was wondering if it is safe in C++ to do the same (based on answers in this, it should be). I have attached my code which compiles to show exactly what I am trying to ask.

I have a function that has a function pointer as its argument. The argument is a function pointer with nonconst arguments but I supply that function with a pointer to a function with const arguments.

GCC did not complain about it and I think it should be safe but want to make sure I am not leaving any details.

typedef uint16_t (myFunction)(uint16_t);

uint16_t increment(const uint16_t input);
uint16_t callFunction(myFunction* function, const uint16_t input);



uint16_t increment(const uint16_t input)
{
    return input + 1;
}


uint16_t callFunction(myFunction* function, const uint16_t input)
{
    return (*function)(input);
}

void setup()
{
    callFunction(increment, 2);
  /* add setup code here */

}

void loop()
{

  /* add main program code here */

}
Ali
  • 139
  • 1
  • 2
  • 11
  • 4
    In C++ it is same, the topmost const volatile qualifiers affect only mutability of parameters inside function body. – Öö Tiib Mar 15 '18 at 11:59
  • I realized what you said above is correct, but if the args are "const int&" and "int&" then the compiler complain. If I look at reference as a pointer, I can understand why it won't work because the const refers to what the pointer points to and not the pointer itself. Could you please verify my understanding so I can add it to my answer, thank you. – Ali Mar 19 '18 at 20:36
  • 1
    Topmost thing in int& is reference that is immutable by its nature and so can not be volatile. – Öö Tiib Mar 19 '18 at 22:56

1 Answers1

0

After reading the comment from Öö Tiib. I decided to make an answer but with some detail so that I can marke the question as answered not wasting other users' time.

Based on the Working Draft, Standard for Programming Language C++ (N4727) in section 16.1 Overloadable declarations

3.4 Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored when determining which function is being declared, defined, or called.

typedef const int cInt;

int f (int);

int f (const int); // redeclaration of f(int)

int f (int) { /* ... */ } // definition of f(int)

int f (cInt) { /* ... */ } // error: redefinition of f(int)

Only the const and volatile type-specifiers at the outermost level of the parameter type specification are ignored in this fashion; const and volatile type-specifiers buried within a parameter type specification are significant and can be used to distinguish overloaded function declarations. In particular, for any type T, “pointer to T”, “pointer to const T”, and “pointer to volatile T” are considered distinct parameter types, as are “reference to T”, “reference to const T”, and “reference to volatile T”.

Based on the description above it is concluded that there must not be any issue.

Ali
  • 139
  • 1
  • 2
  • 11