0

[I edited my question to answer some of the first comments I got.]

It is well known that It is said that adding const to function arguments when we are not planning to modify the value of the inputs within the function is regarded as both a good programming practice and a way of optimising the compilation; see, for instance, the following threads:

Just to make it clearer, I mean this:

int my_function(const int i, const my_struct *p) {

/* where `my_struct` is a large struct previously defined by me */

/* Both `i` (passed by value) and `p` (and/or `*p`?) are meant to remain unchanged during all this function */

[...]

}

However, I've read the following sentence at this C++ tutorial: https://www.cplusplus.com/doc/tutorial/functions/:

Therefore, const references provide functionality similar to passing arguments by value, but with an increased efficiency for parameters of large types. That is why they are extremely popular in C++ for arguments of compound types. Note though, that for most fundamental types, there is no noticeable difference in efficiency, and in some cases, const references may even be less efficient!

So, what are those cases in which adding const to some arguments or parameters of a function may result in a less efficient code?? Any hint or any general rule of thumb?

NOTE: I am programming in C, not in C++. I know that you can only pass variables by value in C. However, I understand that it is still useful to specify when an argument is going to remain unchanged during the function.

I insist: My question is not about passing by reference vs by value. I am programming in C, so I am assuming that arguments are passed by value. My question is about when using const could be not advisable.


EDIT (after my question was reopened):

As some people said in the comments below, I was maybe misunderstanding the text I quoted above, since it seems to be referring to the C++ case, in which variables/arguments/parameters can be passed by reference to functions, which is not the case in C.

Anyway, in the end, my doubt was about whether using const can be inefficient in some contexts, and I think this was already answered in the accepted answer.

Vicent
  • 313
  • 1
  • 3
  • 15
  • 5
    "It is well known that" --> "it is asserted by some that". – John Bollinger Dec 18 '21 at 22:59
  • 3
    `n some cases, const ***references***` And in C there are no references. Are you asking about C or about C++? – KamilCuk Dec 18 '21 at 22:59
  • 1
    Const doesn't cause any efficiency loss there. References/pointer-indirection will, but only for arguments that would otherwise pass through registers (such as pointers or integers) and only if the compiler isn't able to eliminate that indirection through inlining. – Petr Skocik Dec 18 '21 at 23:02
  • 6
    To amplify: the remark on which you are focusing is mostly about pass by value *vs*. pass by reference (which is not even relevant in C). The `const`ness is not directly related to the point. – John Bollinger Dec 18 '21 at 23:02
  • One part of the "inefficiency" is that a pointer or a reference could be a 64-bit address, when an int is 32 bits. So passing *more* data. Also, to pass a pointer or reference the value has to be stored in memory (to get an address), while an int passed by value can be kept in a CPU register. – BoP Dec 18 '21 at 23:07
  • 3
    Also, although some do recommend `const` function parameters as a matter of style and of intent signaling, it has no relationship with optimization for modern compilers. The compiler doesn't need you to tell it whether you modify any particular parameter of variable within the body of the function. – John Bollinger Dec 18 '21 at 23:09
  • @JohnBollinger But in the case of calling between compilation units, you need it in the declaration of reference parameters when the caller is in a different compilation unit. – Barmar Dec 18 '21 at 23:14
  • @JohnBollinger it makes a huge difference for the compiler if you promise to do not change referenced object – 0___________ Dec 18 '21 at 23:20
  • @BoP My question is not about passing by reference or by value. I am programming in C, so I am assuming that arguments are passed by value. My question is about when using `const` could be not advisable. – Vicent Dec 18 '21 at 23:28
  • So, maybe @Barman would like to post an answer... – Vicent Dec 18 '21 at 23:30
  • I sincerely do not understand the down votes here. :/ – Vicent Dec 18 '21 at 23:32
  • “what are those cases in which adding const to some of the arguments or parameters of a function may result in a less efficient code?” — There are none, and the quote doesn’t claim that. You misunderstood it. – Konrad Rudolph Dec 18 '21 at 23:35
  • 1
    @Vincent - In the part you quote about `const reference` it is the reference that is bad, not the const. I tried to explain why. And in C you still have pointers, whch has the same problem - when passing a `const int*`, it is again the `*` that is inefficient, not the `const`. – BoP Dec 18 '21 at 23:38
  • @BoP I think you have the correct explanation of the text that the question is about. You should post that as an answer. It is also applicable to C where a parameter can be passed either by a const pointer or by value. – nielsen Dec 19 '21 at 00:00
  • @Vicent is amiss. `i` and `*p` are to remain unchanged in the function body. `p` may still change. – chux - Reinstate Monica Dec 19 '21 at 00:01
  • 1
    @Vicent The whole quote about C++ is irrelevant to this C question. Its presence has only added noise to the real issue and lowers the value of this question. – chux - Reinstate Monica Dec 19 '21 at 00:03
  • @JohnBollinger Re: [no relationship with optimization for modern compilers.](https://stackoverflow.com/questions/70407770/when-could-it-be-inefficient-to-use-const-for-function-arguments#comment124459402_70407770). Interesting assertion, though not fully convinced `foo(const char *p1, char *p2, const char * restrict p3, char * restrict p4)` has same optimization potential with/without the two `const`. Will ponder. – chux - Reinstate Monica Dec 19 '21 at 00:16
  • @Barmar, this is a question about C. There are no reference parameters. – John Bollinger Dec 19 '21 at 02:49
  • @0___________, it makes a huge difference to the compiler if you attempt to use reference parameters at all. Since the question is about C, we should assume a C compiler, which almost certainly will reject code that tries to use references. – John Bollinger Dec 19 '21 at 02:51
  • @chux-ReinstateMonica, your example does not have any `const` parameters. Non-`const` pointers to `const`-qualified types are not themselves `const`. – John Bollinger Dec 19 '21 at 02:53
  • @JohnBollinger I know, but the quoted text is about C++, and your comment seemed to be addressing it in that context. – Barmar Dec 19 '21 at 02:59
  • @JohnBollinger True, yet OP's example has a mix of both `my_function(const int i, const my_struct *p)` You [comment](https://stackoverflow.com/questions/70407770/when-could-it-be-inefficient-to-use-const-for-function-arguments?noredirect=1#comment124459402_70407770) does not clearly limit to just one of those. – chux - Reinstate Monica Dec 19 '21 at 03:00
  • 2
    This question should not have been closed, at least not for lack of clarity. It is based on a faulty premise, but the question posed nevertheless seems pretty clear. – John Bollinger Dec 19 '21 at 03:28

4 Answers4

3

My question is about when using const could be not advisable.

Not using const in a function definition, to improve efficiency, is not a real concern in C.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
2

The sentence in question is:

Note though, that for most fundamental types, there is no noticeable difference in efficiency, and in some cases, const references may even be less efficient!

Observe that this sentence is talking about fundamental types, such as int or char. If we pass a fundamental type, it is typically simply put into a register to be used by the called routine. If we instead pass it by reference (include by pointer in C), then its address is put into a register instead. Then the called routine must get the value by loading it from memory. Thus passing by reference adds overhead in such cases. It may even be necessary to load the value multiple times if it is used multiple times, because various things could be modifying it. (The fact that it is const to the called routine does not mean it is const to the caller. The object could be pointed to by other pointers that do not include const and/or changed by other routines the called routine calls.)

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
1

In my opinion the most important use of the const keyword is for code clarity. It tells a reader of the source code that this variable is intended to be kept constant. I highly recommend using const for this purpose as often as possible.

I would not worry about using the const keyword for optimization nudging purposes. Compilers are getting better and better at optimizing code and I do not think using const will make a significant difference in practice.

nielsen
  • 5,641
  • 10
  • 27
0

The sentence in the C++ is about passing by reference (special C++ syntax void foo(int &x); - notice the &). There is nothing like passing by reference (in the C++ sense) in C language.

It does not have anything in common with passing by reference in C.

In C const parameters often allow the compiler to use more aggressive optimization methods.

what are those cases in which adding const to some of the arguments or parameters of a function may result in a less efficient code??

*Those cases are related to C++ only and it might happen the compiler will have to create a separate copy of the container when the function is called.

As I wrote in my comment do not read C++ tutorials when you learn C. Those languages have similar syntax (which probably tricked you) but are very different.

As you learn language I would advise you to do not think too much about the micro-optimizations. Beginners very often focus on them, trying to save nanoseconds when their main algorithm is very bad.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0___________
  • 60,014
  • 4
  • 34
  • 74
  • 1
    I believe this is incorrect: “In C const parameters often allow the compiler to use more aggressive optimization methods.” — In fact, [`const` parameters in C don’t allow *any* optimisations](https://nullprogram.com/blog/2016/07/25/), because it is legal for programs to cast away the `const` qualifier and modify the argument. Only `const` in variable *definitions* allow for optimisations. – Konrad Rudolph Dec 19 '21 at 08:35