0

The FILE struct in stdio.h only allows you to access pointers of it because the struct takes up too much space. Why can't we pass an integer like this too? Without creating another copy of it? Why waste four bytes when the alternative way isn't even that complicated? Why not use an integer pointer? If one is worried about one of the developers changing the value, then make it a constant integer pointer. Is there a reason to not pass pointers instead of primitive types?

EDIT: People are saying that sizeof(int)==sizeof(int*), ok but what if I create a long long, then will passing a pointer be the better option?

dfmaaa1
  • 67
  • 6
  • You can pass any object by pointer. But keep in mind that, on many implementations, a pointer is larger than an `int`. – Thomas Jager Sep 02 '22 at 15:35
  • 1
    On 64-bit machines, pointers are 8 bytes long, so in theory, you use more space passing the pointer than passing the value — but the chances are that pointers and values are both passed in registers, so the size difference is moot. Yyou have to do an extra memory access to dereference the pointer to get the value, so passing pointers can lead to some inefficiency. The `FILE` structure is effectively opaque — you aren't supposed to go poking inside it. Passing opaque pointers around is a basic form of information hiding. – Jonathan Leffler Sep 02 '22 at 15:38
  • Whatever you pass (your integer or the address of your integer), a copy of it is passed to the function. – Gerhardh Sep 02 '22 at 15:39
  • 1
    You might want to think about the fact that, regardless of whether you're passing `int` or `int *`, you're still passing by value. – Thomas Jager Sep 02 '22 at 15:41
  • Because a pointer is just an integer with a value that refers to somewhere in memory. – Andrew Henle Sep 02 '22 at 15:51
  • The `FILE` structure probably would take up a lot of space, but also passing a `FILE` by value would be no good because the library functions need to modify the `FILE` when performing operations on the stream, and those side effects need to persist when the library function returns. – Ian Abbott Sep 02 '22 at 16:58

2 Answers2

3

Why can't we pass an integer like this too? Without creating another copy of it?

You can. You can pass the address object x by passing &x (as long as x was not declared with the register storage class keyword). The called function should be defined in a corresponding way, to accept a pointer to that type of object.

If want to pass a value that is not currently in an object, you can use a compound literal to create an object: & (int) { 3 } will create an int object, initialize it with the value three, and take its address.

Why waste four bytes when the alternative way isn't even that complicated?

Pointers take at least four bytes in current typical systems, eight bytes in typical 64-bit platforms. So, if you use a pointer, instead of having a four-byte int, you have both a four-byte int and a four- or eight-byte pointer. Also, int values and pointers are commonly passed in processor registers, not memory, so they would not take any less space if you did not use the whole register.

Why not use an integer pointer?

Since a pointer is not typically smaller than an int, there is no space savings in passing it, and it may take a little extra work to create the address of something rather than using its value directly. It is also likely to cause extra work in the called routine, as it has to use the address to fetch the value from memory instead of using directly from the register it was passed in.

If one is worried about one of the developers changing the value, then make it a constant integer pointer.

Passing a const-qualified pointer to an object does not guarantee the called function will not change it. const was added to the C language late, so it is not fully integrated into the type system and serves more as advice and help in writing correct code than as total enforcement of prohibiting changes.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Ok, but what if I want to pass a long long, then what? Then should I use a pointer? – dfmaaa1 Sep 02 '22 at 17:22
  • @dfmaaa1: It would depend on the situation, including the target platform, how frequently the values were being passed, what they were being used for, and more. `long long` is not very long; you would have to be passing it a huge number of times for any tiny gain, if there is one at all, from passing a pointer instead to be noticeable. It is generally not something a program should worry about until passing structures containing at least dozens of bytes, unless they are targeting an embedded system in a performance-critical project. – Eric Postpischil Sep 02 '22 at 17:28
1

The FILE struct in stdio.h only allows you to access pointers of it because the struct takes up too much space.

That's not why it's passed as a pointer. It's passed as a pointer because the definition of the FILE type itself is hidden from you; you cannot declare instances of the FILE type, you can only declare pointers to it1. Because the type definition is hidden, you cannot directly manipulate the contents of a FILE object. That type definition is only visible within the stdio library.

Why can't we pass an integer like this too? Without creating another copy of it?

You're still creating a copy, it's just that it's a copy of the pointer.

The formal argument of a function is always a separate object in memory than the actual argument in the function call, and it receives the value of the actual argument. That's true whether the argument is a scalar or a struct or union type.

Passing a pointer to an int buys you absolutely nothing over passing it by value in terms of space, and actually can cost more (pointers are 8 bytes wide on most modern systems now).


  1. The size and representation of a pointer does not depend on the size or representation of the pointed-to type.
John Bode
  • 119,563
  • 19
  • 122
  • 198