'How does memccpy handle large integer values?

According to man 3 memccpy the memccpy function is defined as follows:

SYNOPSIS

#include <string.h>

void *memccpy(void *dest, const void *src, int c, size_t n);

DESCRIPTION

The memccpy() function copies no more than n bytes from memory area src to memory area dest, stopping when the character c is found.

If the memory areas overlap, the results are undefined.

What confuses me is that memccpy copies n bytes and stops if character c is found. However, the function takes int c as an argument. So what happens if I call memccpy with the following value:

memccpy(&x, &y, 0xffffff76, 100);

Here the value to check is too big for char. Should this case work?



Solution 1:[1]

how exactly this case is handled in code

Just the value of the parameter is converted to a character:

void *memccpy(..., int param_c, ...) {
     unsigned char c = param_c;

In real life : https://github.com/lattera/glibc/blob/master/string/memccpy.c#L33 https://github.com/lattera/glibc/blob/master/string/memchr.c#L63 .

(On nowadays systems) unsigned char has 8 bits, (unsigned char)(int)0xffffff76 just becomes 0x76. The upper bits are just ignored.

Solution 2:[2]

This is an older function which is similar to memset in terms of the argument it accepts:

void *memset(void *s, int c, size_t n);

It is described in the C standard as follows:

The memset function copies the value of c (converted to an unsigned char) into each of the first n characters of the object pointed to by s.

Both functions date back to at least 4.3 BSD, so it would make sense that they handle their arguments in a similar way.

So given your example, the value 0xffffff76 would be converted to the unsigned char value 0x76, and that would be the value it check for to stop.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 KamilCuk
Solution 2 dbush