1

I see some code that passes some structures by pointer to a function that doesn't changes the values that the pointer points to, like this one:

typedef struct __spi_handle_t {
    uint16_t  TxXferSize;  /* SPI Tx transfer size */
    uint16_t  RxXferSize;  /* SPI Rx transfer size */
    uint16_t  RxXferCount; /* SPI Rx Transfer Counter */
} spi_handle_t;

void hal_spi_init(spi_handle_t *spi_handle);

What is the point of making this rather than just passing by value?

Jorengarenar
  • 2,705
  • 5
  • 23
  • 60
  • 1
    In C, there is no passing by reference, only by value and pointer – Jorengarenar Jul 26 '20 at 23:51
  • @kaylum yes, thank you – Ahmed Abdalrahiem Jul 27 '20 at 00:02
  • @Jorengarenar Passing "by pointer" is passing by value... – Déjà vu Jul 27 '20 at 00:06
  • @e2-e4 And so is passing by reference. Of course it's passing by value, because you need to pass the pointer value, but it isn't actual value you desire to operate. You use a middleman (pointer) to pass the actual data, hence it's called passing by pointer. – Jorengarenar Jul 27 '20 at 00:07
  • @Jorengarenar: When discussing C, “passing by reference” means passing by pointer. This is long standing usage prior to C++’s creation of a reference type, and it did not become incorrect in C when C++ used the word as it does. The C standard uses “reference” for the act of referring to objects by pointers; see my [comments below](https://stackoverflow.com/questions/63106974/why-pass-by-pointer-to-a-c-function#comment111594123_63107000). – Eric Postpischil Jul 27 '20 at 00:27
  • passing by value creates a copy (ints, structs, whatever), by reference is just a pointer so if the struct/int/etc are smaller than a pointer then its not as costly but if it is a struct then the copy often consumes stack space. But struct or int it depends on if you want it modified in the callee function or not, and choose the right option for that design decision. – old_timer Jul 27 '20 at 00:45
  • you will often see this to avoid using a global variable. passing a struct on down through nested functions so that each function has access to the global/top level information... again a design decision, it has a cost vs using a global. and you would pass by reference for this use case to avoid adding even more cost to the code. – old_timer Jul 27 '20 at 00:47
  • In this particular case, it’s so that the `hal_spi_init` can update the contents of `spi_handle`. If you want a function to write to a parameter, you have to pass a pointer to that parameter (think of the `scanf` library function). – John Bode Jul 27 '20 at 01:20

2 Answers2

3

Structures can be very large, so attempting to pass them by value can result in inefficiencies.

By passing a pointer to the struct, it reduces the overhead to just a single pointer.

dbush
  • 205,898
  • 23
  • 218
  • 273
2

so, what is the point of making this rather than just passing by value?

The code in hal_spi_init is actually passing by pointer, not reference. In C there is no reference type.

The point of passing pointer (instead of passing by value) is to avoid expensive copy. It doesn't matter much in this case as spi_handle_t is pretty small. But would be big difference if spi_handle_t is a huge struct.

Also passing pointer would allow to change the original struct directly inside hal_spi_init - passing value would not be possible to do so (ie changing the original struct from the caller).

artm
  • 17,291
  • 6
  • 38
  • 54
  • i see that in most cases this will be useful to pass by pointer rather than passing by value. so, when to decide to pass by value or by pointer? – Ahmed Abdalrahiem Jul 26 '20 at 23:55
  • @CherryDT that's right, was typing about it.. – artm Jul 26 '20 at 23:57
  • @AhmedAbdalrahiem you should pass value for basic/small data types ie `int` or `bool` types. Most of other cases, passing pointer is the way to go in C. – artm Jul 27 '20 at 00:00
  • is there a point behind this convevntion,sir? @artm – Ahmed Abdalrahiem Jul 27 '20 at 00:03
  • Re “not reference”: This is an attempted retroactive change to the terminology used for C, and answers should not chastise users for using it and particularly should not lead with it. Before C++ made something it called a “reference,” the term meant, and still means, a way of giving some sort of handle or address to something. A pointer is a reference, and passing by pointer is passing by reference. The C standard refers at one point to a pointer that references an array and at another to an object referenced through a pointer. In 7.29.6, it refers to a “referenced object” passed via pointer. – Eric Postpischil Jul 27 '20 at 00:23
  • You may choose not to use the terminology “pass by reference” when discussing C, but it is not right to correct others who do use it. The terminology did not become incorrect in C when C++ adopted it for something particular in that language. – Eric Postpischil Jul 27 '20 at 00:24
  • @EricPostpischil so "pass by reference" is ok in C, and it actually means "pass by pointer", is that what you meant? – artm Jul 27 '20 at 01:21
  • @artm: Yes, a pointer refers to an object, so, when discussing C, “pass by reference” means pass by pointer. Historically, people knew what that phrase meant. It has not changed in C. – Eric Postpischil Jul 27 '20 at 01:31
  • @artm: C passes *all* function arguments by value, period, no exceptions. Sometimes, those values are pointers, and we use pointers to *fake* pass by reference semantics (that is, to allow the function to write a new value to its arguments). Some people call it “pass by reference” as a shorthand for what’s really going on. – John Bode Jul 27 '20 at 01:40
  • @JohnBode "C passes all function arguments by value, period, no exceptions." Yes that's definite. Pass by pointer and pass by reference are just different ways to say the intention: "want to pass the original object to this function instead of a copy of it". – artm Jul 27 '20 at 02:20