2

I am learning about side-effects and pure functions. I know that pure functions have no side-effects and their return value is the same for the same arguments. I would like to know whether the C function strcmp() is a pure function. I believe that it is pure, due to the fact that given the same two strings as parameters, the result will always be the same. Furthermore, strcmp() does not modify any variables or call any functions, thus it does not have any side effects.

However I am not sure whether my reasoning is correct.

klutt
  • 30,332
  • 17
  • 55
  • 95
ceno980
  • 2,003
  • 1
  • 19
  • 37
  • 5
    `given the same two strings as parameters` you don't give strings, you give pointers. – KamilCuk Jul 26 '19 at 08:26
  • 3
    @KamilCuk hmm, this is interesting. If you give the same *pointers* to `strcmp` you are not going to necessarily get the same result as there might be different data at the end of those. And if you give pointers to the same *strings*, that's not necessarily the same input value-wise to `strcmp`. – VLAZ Jul 26 '19 at 08:29
  • For example gcc compiler has "const" and "pure" [function attribute](https://embarc.org/man-pages/gcc/Common-Function-Attributes.html). In that description, `memcmp` could be "pure", but may not be "const". "const" functions cannot access the values behind the pointers. – KamilCuk Jul 26 '19 at 08:36
  • 2
    @KamilCuk Both `memcmp` and `strcmp` have the same "pureness" problems, in that it's passed pointers to data. Two calls may have the same pointers, but may give different result if the data the pointers are pointing to have changed between the calls. That makes them, in a way, impure. – Some programmer dude Jul 26 '19 at 08:42

3 Answers3

3

strcmp() is a pure function, since the result is dependant solely on the parameters and in addition, it does not modify a global state.

Of course, improper use of strcmp() may invoke undefined behaviour, but this is not relevant for it being pure or impure.

Edit:

A pure function only yields the same results, when the global memory referenced is also the same. Functions, which do not require that are called constant functions.

GCC documentation provides strlen() as an example of a pure function. Indeed, this function takes a pointer as a parameter, and accesses it to find its length. This function reads global memory (the memory pointed to by parameters is not considered a parameter), but does not change it, and the value returned derives from the global memory accessed.

Ctx
  • 18,090
  • 24
  • 36
  • 51
2

The behavior of strcmp(), like that of strlen() depends only on the contents of the memory pointed to by the const char * arguments. No side effects are intended to occur, and if the potential changes in the virtual memory management system are considered invisible to the program, it can be considered pure.

Note however that the closely related function strcoll() may have side effects depending on the locale handling implementation, and should not be considered pure.

Similarly isdigit() is pure but isalpha() is not.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
1

It's not pure, in the sense that the arguments are mutable. This means that the result of calling strcmp(a, b) will depend on what those pointers are pointing at. The return value should only depend on the value of the arguments.

Another requirement for a pure function is that it has no side effects. This is fulfilled. Well, in practice it is. It depends on how you see it. I can almost promise that all implementations of it has no side effects, but the standard itself does not require them to have no side effects.

In general, you can for all relevant purposes assume that it is does not have side effects. The only exception is if the call invokes undefined behavior, but that's something you should avoid anyway.

Further strcmp() does not modify any variables or call any functions, thus it does not have any side effects.

You cannot say for sure that it does not call any functions. That's implementation details.

klutt
  • 30,332
  • 17
  • 55
  • 95
  • Of course you are right, but if `strcmp()` really did something else, i.e. modified a global state which leads to different behaviour of the program than the pure implementation would, then the implementation would not be standard conform. – Ctx Jul 26 '19 at 08:47
  • @Ctx Where in the standard can I read that it would not conform to the standard? – klutt Jul 26 '19 at 08:50
  • This is not necessary. You just have to provide an example, where a `strcmp()` version with side effects would lead to different behaviour of a program than a version without side effects. – Ctx Jul 26 '19 at 08:52
  • @Ctx Some functions modifies the global `errno`. As far as I know, it's perfectly ok for an implementation to add an additional global for similar stuff. – klutt Jul 26 '19 at 17:37
  • Only if it is documented, which it isn't for strcmp() – Ctx Jul 26 '19 at 18:22
  • @Ctx Yes, but does the standard explicitly say that a function modifying such globals violates the standard? – klutt Jul 26 '19 at 23:01
  • If you do a strcmp() between an errno modifying function and evaluation of the errno, and this call modifies errno, this is of course not standard compliant. If it modifies some global, which isn't used anywhere and thus doesn't affect the code flow, I would considee it still as pure function. – Ctx Jul 27 '19 at 10:14