1

I have a pointer which points to a function. I would like to:

  if (mode == 0)
  {
  const unsigned char *packet = read_serial_packet(src, &len);

  } else {
  const unsigned char *packet = read_network_packet(fd, &len);
  }

But I cannot do it because my compiler complains when I first use the pointer later in the code.

   error: 'packet' undeclared (first use in this function)

This is strange. It worked without the if statement, but now I need my program to be able to get data from different sources. Isn't it possible to do this? I think so. If it isn't, is there any other simple way to get what I am trying?

Thanks a lot.

Tadeusz A. Kadłubowski
  • 8,047
  • 1
  • 30
  • 37
echedey lorenzo
  • 377
  • 1
  • 5
  • 19
  • 1
    One way of being clear about the purpose of `const` is to place it near the variable name but on the correct side of the star.. i.e. `unsigned char const *packet` is read as "pointer to const unsigned char". Where as `unsigned char * const packet` is read as "constant pointer to unsigned char". If you read backwards through the line it is easy to remember what type of pointer you have. – PP. Mar 21 '10 at 18:42
  • 2
    Also i should be noted that you do not have a pointer to a function. You have a character pointer which is being used to store the return value of a function. – Graphics Noob Mar 21 '10 at 18:54
  • I'm not very skilled in managing this kind of low level pointers in C. I take care of your advices so I can become a better C programmer. Thanks. – echedey lorenzo Mar 21 '10 at 22:39

8 Answers8

16

You need to review the concept of blocks or compound-statements, or variable scope.

If you declare a variable in a compound statement ({, }), the variable will be declared only in that exact scope.

Thus, change your code to

const unsigned char *packet = NULL;
if (mode == 0)
{
   packet = read_serial_packet(src, &len);
} else {
   packet = read_network_packet(fd, &len);
}

// Now you can perform operations on packet. 
mnemosyn
  • 45,391
  • 6
  • 76
  • 82
11

Any kind of brackets will put it out of scope, even if not a construct like for, while, or if.

i.e.

{
    int num = 2;
}
num++; // error: out of scope!

Also, you can just ternary it:

const unsigned char *packet = (mode == 0) ? read_serial_packet(src, &len) : read_network_packet(fd, &len);
y2k
  • 65,388
  • 27
  • 61
  • 86
7

Variables declared in a block aren't seen outside it.

  if (mode == 0)
  {
    const unsigned char *packet = read_serial_packet(src, &len);
    // packet can be used here
  } else {
    const unsigned char *packet = read_network_packet(fd, &len);
    // packet can be used here
  }

  // packet can not be used here

You must declare packet before the if and assign it in if and else according to your condition:

const unsigned char *packet;

if (mode == 0)
{
  packet = read_serial_packet(src, &len);
}
else
{
  packet = read_network_packet(fd, &len);
}

// packet can be used here
Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
3

This is because curly braces { } make a new scope. This means that every variable defined between these braces is defined within a scope and hence not visible outside of it.

To make it work you need to define *packet before if-else:

const unsigned char *packet = 0;
if (mode == 0)
{
    packet = read_serial_packet(src, &len);
} 
else {
    packet = read_network_packet(fd, &len);
}
pajton
  • 15,828
  • 8
  • 54
  • 65
  • 1
    The characters inside the packet (after the pointer) won't change. The pointer may change anytime. – Potatoswatter Mar 21 '10 at 18:38
  • I second @Potatoswatter's comment: you can still declare the pointer to `unsigned char const` in this example. – PP. Mar 21 '10 at 18:44
2

You can't declare variables inside an if statement and then use them later, for the simple reason that this would be a non existent memory location for some paths through the program.

EDIT: So declare it earlier.

Rob Lachlan
  • 14,289
  • 5
  • 49
  • 99
2

When you define a variable, you can only use it within the defined scope.

{
    const unsigned char *packet = read_serial_packet(src, &len);

    // packet goes out of scope when the block ends
} 

So you need to move your definition to the biggest scope you need:

{
    const unsigned char *packet;

    {
        packet = read_serial_packet(src, &len);

    }

    // packet still in scope here

}

// and packet is no longer in scope here 
R Samuel Klatchko
  • 74,869
  • 16
  • 134
  • 187
2

Declare the pointer before the if statement as:

const unsigned char *packet;
if (mode == 0) {
    packet = read_serial_packet(src, &len);

} else {
    packet = read_network_packet(fd, &len);
}
codaddict
  • 445,704
  • 82
  • 492
  • 529
1

The declaration of the pointer inside if statement clause scopes it up to the end of the if statement. You should declare your pointer outside if statement and do the assignment inside.

Eimantas
  • 48,927
  • 17
  • 132
  • 168