4

I'm a rather experience C++ programmer, but with (pure!?) C-code I am sometimes struggling, especially when I haven't used it in a while. Can someone give me a hint on why the code below is not working? Compiler says:

syntax error : missing ')' before '&'

complaining about the line that has the printItem-signature. How I can make it work? Is the only option to change the printItem-signature to:

void printItem(const struct structItem *const item)
{   
    printf("age: %i, price: %i", item->age, item->price);
}

Or is there another way, that would allow me to keep the signature as it is below? Also, ...I didn't use the more convenient "typedef" notation for the struct, because I remember some issues with that - possibly in this context. If anyone could shed some light on all this, I would be very thankful.

#include <stdio.h>

struct structItem {
    int age;
    int price;
};

void printItem(const struct structItem &item)
{   
    printf("age: %i, price: %i", item.age, item.price);
}

int main()
{
    struct structItem item;
    item.age = 1;
    item.price = 200;

    printItem(item);

    getchar();

    return 0;
}
AudioDroid
  • 2,292
  • 2
  • 20
  • 31
  • What do you mean when you say that the C code isn't working? Is it not compiling, or faulting, or giving a wrong answer? – Adam Mihalcin Feb 20 '12 at 23:33
  • Oh, it's not compiling. I'll edit the text. Sorry. – AudioDroid Feb 20 '12 at 23:33
  • @AdamMihalcin: It's a C program, trying to use `&` to denote a reference. Do you really have to ask what's not working? – ruakh Feb 20 '12 at 23:35
  • 2
    i dont think C has a pass by reference so it'll have to be passed by pointer – Dampsquid Feb 20 '12 at 23:35
  • @ruakh Forgive me for assuming that the question referred to *both* forms of the `printItem` function, both with the double-`const` pointer and with the reference. – Adam Mihalcin Feb 20 '12 at 23:40
  • @AdamMihalcin: Well, the question explicitly stated otherwise; but I can't pretend that *I*'ve never missed part of a question, so yes, I forgive you for doing so. :-P – ruakh Feb 20 '12 at 23:46
  • @ruakh I understand why you might say that, but I made my comment *before* the edit that added the compiler error message. – Adam Mihalcin Feb 21 '12 at 01:06
  • @AdamMihalcin: Sorry, but you *don't* understand. The question explicitly asks -- and has *always* explicitly asked -- if the only fix is to change from the method signature with `&` to the method signature with `*`. It's obvious why the version with `&` wasn't working, and you had no basis for assuming that the `*` wasn't working, because the OP was explicitly asking if it was the *only* way that *would* work. – ruakh Feb 21 '12 at 01:11

6 Answers6

4

In C, you must pass by pointers so you would define printItem like this:

void printItem(struct structItem *item)
{
    printf("age: %i, price: %i", item->age, item->price);
}

To call it, give it the pointer. E.g.:

printItem(&item);
Don Cruickshank
  • 5,641
  • 6
  • 48
  • 48
2
int main()
{
    struct structItem item;
    item.age = 1;
    item.price = 200;

    printItem(item);

At this point, you're passing the entire structure to the printItem() function. The compiler will (semantically, if not actually) copy the structure into temporary storage for your function. If you want to pass the address of the item structure, amend the call:

    printItem(&item);

You'll need to amend the prototype for printItem() anyway, as this is not legal C:

void printItem(const struct structItem &item)

GCC throws an error:

$ make item
cc     item.c   -o item
item.c:8:40: error: expected ‘;’, ‘,’ or ‘)’ before ‘&’ token

Change the & to * in the function prototype, to declare that the function takes a pointer to a structItem, amend the function to use -> to access structure members through a pointer, and the full program is:

#include <stdio.h>

struct structItem {
    int age;
    int price;
};

void printItem(const struct structItem *item)
{
    printf("age: %i, price: %i", item->age, item->price);
}

int main()
{
    struct structItem item;
    item.age = 1;
    item.price = 200;

    printItem(&item);

    getchar();

    return 0;
}
sarnold
  • 102,305
  • 22
  • 181
  • 238
2

The References are C++ syntax. In pure C you can only use call-by-reference with Pointers.

void printItem(const struct structItem* const item) {
    printf("age: %i, price: %i", item->age, item->price);
}

And be carefull with the function-call. You need to call it with the adress of the structure.

struct structItem item;
item.age = 1;
item.price = 200;

printItem(&item);
Jan Koester
  • 1,178
  • 12
  • 26
1

References aren't part of the C syntax, so you'll have to change it to the void printItem(const struct structItem *const item) signature you gave in the question, and change the call accordingly, i.e. printItem(&item);

Even Jon Skeet says so: Does C have references?

Community
  • 1
  • 1
je4d
  • 7,628
  • 32
  • 46
0

With a struct that small, you might as well pass by value:

void printItem(struct structItem item) {
    printf("age: %i, price: %i\n", item.age, item.price);
}

This is faster since no dereferencing is required, and passing by value makes it clear that the item will not be modified.

Dave
  • 10,964
  • 3
  • 32
  • 54
  • In this particular context I agree. However I just made up this example to narrow down the problem. In my real example the struct is MUCH bigger. – AudioDroid Feb 21 '12 at 00:15
-1

The problem that appears to be causing the build break is

void printItem(const struct structItem *const item)

There is no reason to use the const keyword twice; in fact, it's illegal. Even with the standards compliance cranked way up, I can still compile

#include <stdio.h>

struct structItem {
    int age;
    int price;
};

void printItem(const struct structItem *item) {
    printf("age: %i, price: %i\n", item->age, item->price);
}

int main(void) {
    struct structItem item;
    item.age = 10;
    item.price = 100;

    printItem(&item);
    return 0;
}

no problem, and the program prints

age: 10, price: 100

as expected.

Adam Mihalcin
  • 14,242
  • 4
  • 36
  • 52
  • 1
    Hm. I don't think using the const keyword twice is a problem. It assures that I don't redirect the pointer inside the function. I just tried it. With the second const, it won't allow me to redirect the pointer. That's what I want, and it works fine. – AudioDroid Feb 21 '12 at 00:06