I’d like to refactor some old C code of mine, and I was curious if I can replace all ptr++ with ptr += 1 where ptris some pointer, without changing any behavior. Here’s an example of what I mean, from K&R Section 5.3:
/* strlen: return length of string s*/
int strlen(char *s)
{
int n;
for (n = 0; *s != '\0'; s++)
n++;
return n;
}
When I replace the s++ with s += 1, I get the same results, but I’m wondering if this will be the case for all types. I also did a test for ints:
int size = 10;
int *int_array = (int*)calloc(size, sizeof(int));
for (int i = 0; i < size; i++)
int_array[i] = i;
for (int i = 0; i < size; i++) {
printf("*int_array = %d\n", i, *int_array);
int_array++;
}
If I replace the line int_array++; with int_array += 1;, I get the same result.
After thinking about this some more, I realize there could be a problem if the value is used in an expression. Would it be safer I just moved the increment onto another line like so:
int a = 5;
int b = a++;
would become:
int a = 5;
int b = a;
a += 1;
Conclusion
What I thought could be a problem, incrementing pointers of different types, is not a problem. See @bdonlan’s response for the reason why.
This doesn’t mean that you can replace all x++ with x += 1 and expect the same behavior. You can, however, replace ++x with (x += 1) safely, since they are equivalent.
a += 1is equivalent to++a(C99 §6.5.3.1/2). In a line likeint b = a++;this means it is not equivalent toa++;a++would return the old value ofa, whilea += 1returns the new value.Note that if you don’t use the result of
a++(ie, you have a statement containing justa++;), then they are effectively identical.Also, note that _all pointer arithmetic is done in increments of the pointed-to type’s size (§6.5.6/8). This means that:
is equivalent to:
This is the same whether you use
+,++,+=, or[](p[x]is exactly equivalent to*(p + x); you can even do things like4["Hello"]because of this).