92

memset() is declared to return void* that is always the same value as the address passed into the function.

What's the use of the return value? Why does it not return void?

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • Consistency with the other `mem*` functions perhaps which mostly return `void*`? – Component 10 Dec 05 '12 at 09:59
  • 9
    http://thevirtualmachinist.blogspot.co.uk/2010/08/whats-return-value-of-memset.html – BoBTFish Dec 05 '12 at 09:59
  • Good simple question that is not trivially answered by google. – Sebastian Mach Dec 05 '12 at 10:02
  • @BoBTFish There's a nice point he makes in the last para. May be we could have that as an answer too.. – UltraInstinct Dec 05 '12 at 10:02
  • 3
    What's the use of the return value of `strcat()`? Sometimes, standard functions are what they are specified to be, not what they *should* be. – DevSolar Dec 05 '12 at 10:18
  • http://stackoverflow.com/questions/3561427/strcpy-return-value – NPE Dec 05 '12 at 10:22
  • 1
    I would like to ask the **reverse** question. What's the point of `void` return values ? Isn't it better to always return something (and the more meaningful the better) ? – Matthieu M. Dec 05 '12 at 10:28
  • @Matthieu M.: Well, I'd guess there's nothing useful to return in many cases. Like what would "kill all humans" function return? – sharptooth Dec 05 '12 at 10:29
  • 4
    @MatthieuM.: Also, there's generally a non-zero cost associated with returning stuff. Even if the return value fits in a register, you generally need to load that value into the register. This has a cost, however small. – NPE Dec 05 '12 at 10:39
  • 1
    @NPE: I would not worry too much about such trivia. In the case the function is inlined, then it's a non-issue (the value if unused will be discarded by the compiler); in the case the function is not inlined *and* the compiler did not use the register as scratch pad for this value (optimization during register allocation), then it it likely to be negligible anyway. – Matthieu M. Dec 05 '12 at 13:00
  • 16
    @sharptooth: A "kill all humans" function would return the number of humans killed, of course. – indiv Dec 05 '12 at 14:31
  • void* is used for returning any of the data type.. that is dynamically decided. A pointer of one type can not point to any other type. So if a user is not sure which type of data to be returned, (eg. for template cases) void* is a good option. – codeofnode Dec 05 '12 at 14:47
  • After reading the answers, I think that might be correct. But it will certainly be a lot cleaner to not chain, and write them as separate lines. That's just a kind of great mystery in life. LOL – Shane Hsu Dec 12 '12 at 15:28
  • 1
    @indiv: ..or, a pointer to the mass grave :) – Carl Dec 14 '12 at 01:02
  • 3
    @MatthieuM.: *You* wouldn't worry about such trivia, but *I* certainly might. What if I'm writing a compiler for a limited resource system? Hmmm? – Thomas Eding Dec 18 '12 at 22:43
  • The return value of a function and the first parameters of a function call likely use the same scratch registers. The memset function can be optimised to leave this register intact without an extra cost for doing so. Therefore, when calling "otherFunction(memset(...));", the address would already be loaded in the first parameter and does not need to be loaded again. So the Instruction Call to memset can be followed immediately with an Instruction Call to otherFunction - without requiring instructions to load "memory" into the first parameter. – le_top Feb 27 '19 at 09:30
  • In C++, `fill_n` returns the pointer past the last one to which it is assigned, which would be equivalent to returning `dest + n`. This is in turn consistent with what it makes sense to return for generalized pointers (iterators). – alfC Aug 16 '19 at 00:28

4 Answers4

125

It may be used for call chaining like:

char a[200];
strcpy(memset(a, 0, 200), "bla");
Juraj Blaho
  • 13,301
  • 7
  • 50
  • 96
  • 9
    Yes, it's definitely the 'chaining' use case. – Cartesius00 Dec 05 '12 at 09:59
  • 7
    I've upvoted the answer, because it's an interesting case. But in real life I think it's better to keep the memset and strcpy calls separate. – Tsvetomir Dimitrov Dec 12 '12 at 12:33
  • 28
    C programmers love unreadable code, so allowing for infinite chaining is a must when designing a standard function. – Chad Schouggins Dec 13 '12 at 03:58
  • @ChadSchouggins Read some haskell code and you know that c-programmers are actually pretty verbatim ;) (thinks of regex "operator" =~)... – BitTickler Apr 23 '15 at 12:58
  • Of course in this example it would have made more sense even, the other way around, for `strcpy` to return the pointer past the last one copied. `memset(my_strcpy(a, "bla"), 0, a + 200);` (like `std::copy_n` and `std::fill_n` do in C++). – alfC Aug 16 '19 at 00:34
36

The signature is in line with all the other similar functions: memcpy(), strcpy() etc. I always thought this was done to enable one to chain calls to such functions, and to otherwise use such calls in expressions.

That said, I've never come across a real-world situation where I would feel compelled to use the return value in such a manner.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
12

In order to use the function as an argument for another function such as sprintf

Romain Francois
  • 17,432
  • 3
  • 51
  • 77
Noah
  • 121
  • 3
3

I came across this question when Googling to see what memset returned.

I have some code where I test for one value, then if that is true test to see if a value is zeros.

Because there is no completely portable way in C to test for zeros I have to run memset in the middle.

So my code is:

if ( a==true && (memcmp(memset(zeros, 0, sizeof(zeros)), b, sizeof(zeros)) == 0) )

This speaks to the chaining purpose listed in the previous questions, but it is an example of a use for this technique.

I'll leave it to others to judge if this is good coding or not.