2

In cstring.h file there exists a function:

int strcmp ( const char *s1, const char *s2 ), but why only the data is constant, isn't it more safe to make both pointer and data constant.In my opinion the correct version of function should be like:

int strcmp ( const char * const s1, const char * const s2 )
Jk1
  • 11,233
  • 9
  • 54
  • 64
Davut Özcan
  • 109
  • 13
  • There is no `cstring.h`. There's `cstring` and `string.h`. – chris Mar 28 '14 at 13:01
  • I agree. Although, it makes absolutely no difference to the caller whatsoever. I do try to do this though. – Ben Mar 28 '14 at 13:01
  • In a declaration, it's extra noise. In a definition, it's generally a good idea to make whatever you can `const`. – chris Mar 28 '14 at 13:02
  • @chris The definition can be const while the declaration isn't? – Ben Mar 28 '14 at 13:03
  • 1
    @Ben, It sure can as long as they're top-level. – chris Mar 28 '14 at 13:04
  • Just for completeness, parameter *names* are also ignored in declarations. – fredoverflow Mar 28 '14 at 13:13
  • @FredOverflow Good point. `int strcmp( char const* s1, char const* s2 )` and `int strcmp( char const* const x, char const* const y)` both declare the same function. – James Kanze Mar 28 '14 at 13:16
  • 1
    possible duplicate of [Use of 'const' for function parameters](http://stackoverflow.com/questions/117293/use-of-const-for-function-parameters) – Raymond Chen Mar 28 '14 at 13:16
  • Well, at least parameter names in those declarations have a use: The client gets a hint what those parameters are for. – Deduplicator Mar 28 '14 at 13:20
  • @James You don't even have to bother the parser with meaningless names: `int strcmp(const char*, const char*);` – fredoverflow Mar 28 '14 at 13:20
  • @Deduplicator It depends. I would argue that if you name your parameters `s1` and `s2` or `x` and `y`, then you could just as well leave the names out completely. – fredoverflow Mar 28 '14 at 13:21
  • @Fred: Of course you can use meaningless names. x, y, n and the like might be short, but depending on the function name, they may convey all the information needed. (Just for on-upmanship, your absolute does not reign unconstrained. ;-) ) – Deduplicator Mar 28 '14 at 13:26

3 Answers3

7

Top-level const modifiers of parameters are stripped from declarations, because they do not concern the client. Whether parameters are changed or not is an implementation detail. It is perfectly valid to declare a function as void f(int x) and then later define it as void f(const int x) (and vice versa).

In your example, even if s1 and s2 are modified inside strcmp, the client does not notice these modifications, because the pointers are passed by value (copied into the function). That is, if you call strcmp(a, b), then a and b will retain their values, even if str1 and str2 are changed.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • But isnt it recommended to use const , if you dont change values – Davut Özcan Mar 28 '14 at 13:04
  • 2
    The client does not need to know (and has no way of knowing) whether `s1` and `s2` are modified inside `strcmp`. There would be no point in adding the `const`. The compiler strips it out, anyway. – fredoverflow Mar 28 '14 at 13:08
  • 1
    @DavutÖzcan Maybe this wasnt stated clearly here: Passing by value will result in a **copy**, thus const is completely meaningless for the caller, as there is **no way** that his passed arguments could be modified, whether const or not. – Sebastian Hoffmann Mar 28 '14 at 13:10
  • @FredOverflow And typically, top level `const` isn't used for local variables anyway. (Whether this is a good thing or not is another question, but in all of the different companies I've worked in, only one ever used const on local variables.) – James Kanze Mar 28 '14 at 13:11
  • @JamesKanze: amusing, I tend to use it for any variable that will not vary. – Matthieu M. Mar 28 '14 at 13:24
  • @MatthieuM. Yes. That's the policy here, as well, but this is the first place I've seen it. (IMHO: if your functions are long enough that you can't immediately see whether a local variable is modified or not, they're too long. But it depends somewhat on the application domain; in numeric processing, functions tend to be longer than elsewhere, and the `const` can be useful.) – James Kanze Mar 28 '14 at 18:22
  • @JamesKanze: actually, I use it even on very small functions; for example `Val* find(std::map& m, Key const& k) { auto const it = m.find(k); return it != m.end() ? &it->second : nullptr; }` :) – Matthieu M. Mar 28 '14 at 18:26
  • @MatthieuM. There's nothing wrong with that, either; it's just not been the usual practice in places where I work. – James Kanze Mar 28 '14 at 18:37
2

As others have pointed out, the top level const is ignored in the declaration; the most frequent convention I've seen has been to forbid it.

It does have meaning in the definition. But the most frequent implementation of strcmp is something like:

int
strcmp( char const* s1, char const* s2 )
{
    while ( *s1 != '\0' && *s2 != '\0' && *s1 == *s2 ) {
        ++ s1;
        ++ s2;
    }
    return (unsigned char)( *s1 ) - (unsigned char)( *s2 );
}

The parameters aren't const.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • `*s1 != '\0' && *s1 == *s2` implies `*s2 != '\0'`; no need to check `*s2 != '\0'` explicitly. – fredoverflow Mar 28 '14 at 13:11
  • @FredOverflow And there are probably other improvements which could be made as well:-). The only real point is that all of the implementations I've seen do use the arguments directly, modifying them. – James Kanze Mar 28 '14 at 13:15
  • The most prominent example probably being `while ((*dst++ = *src++));` inside `strcpy` ;) – fredoverflow Mar 28 '14 at 13:16
  • @FredOverflow As an example of what not to do:-). But yes, such code has existed (and been supported) since the earliest days of C. – James Kanze Mar 28 '14 at 17:51
1

It's not necessary. As the pointers are copied, I don't see how adding one more const makes anything safer?

And, most probably, the implementation changes the s1 and s2 pointers (probably in some loop, incrementing both pointers to compare each char, one by one).

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
  • Yes it is possible to implement algorithm by changing pointer values , but reverse is also possible.Same algorith can be implemented using '[]' operator. – Davut Özcan Mar 28 '14 at 13:06
  • @DavutÖzcan It could be, but it would be very unidiomatic. – James Kanze Mar 28 '14 at 13:09
  • @DavutÖzcan - what James says is true, plus it will lead to adding (at least) one more variable - index, which will slower down the execution (yes, it's a minor thing, but it's something). – Kiril Kirov Mar 28 '14 at 13:11