What is the difference between fread(&buffer...) and fread(buffer...)

Viewed 107

I'm trying to read from a file and copy it to another file. I am reviewing some codes online and I seem to notice that some declare fread this way:

fread (buffer, 1, 1000, src)

some this way

fread (&buffer, 1, 1000, src)

Let's say I have already declared this:

typedef uint8_t BYTE;
BYTE buffer[1000];

How would those two be different?

2 Answers

&buffer returns a pointer to the array. The pointer has type BYTE (*)[1000].

When an array is used where a pointer is expected, it degenerates into a pointer to its first element, so buffer is equivalent to &(buffer[0]) in this situation. The pointer has type BYTE*.

Both pointers point to the same address.

In this case, there is no difference. The specification for fread is (C17 7.21.8.1):

   size_t fread(void * restrict ptr,
   size_t size, size_t nmemb,
   FILE * restrict stream);

The fread function reads, into the array pointed to by ptr...

  • buffer when used in an expression "decays" into a pointer to the first element. It will become type uint8_t* pointing at buffer[0].
  • &buffer takes the address of the array and an expression with & as operator to an array will not make it "decay". The resulting type is a pointer to array, uint8 (*)[1000], which points at the address where the array begins. Which is also where buffer[0] is stored, so it is the same one as above.

Either of these will give the same address and either will work, as far as fread is concerned. Reading the standard pedantically, &buffer is actually more correct.


Unrelated to your question, typedef uint8_t BYTE; is horrible practice. Don't invent your own language with typedefs - by doing so you only make your code strange and less readable. Stick to the standard types as already available from stdint.h.

Related