tags:

views:

261

answers:

7

I've faced three separate situations in C lately that I would assistance on:

  1. My C code has a global variable:

    int ref_buf; //declared in a header file
    

    In a function definition I use the same name as a parameter:

    void fun(int ref_buf, param2, param3)
    {
    }
    

    Will it overwrite the originally defined global variable and will it cause bugs?

  2. Can I declare a static variable in a C data structure like so?:

    struct my
    {
        int a;
        static int b;
    };
    

    Does it work? Is there any specific situation where one would need it?

  3. Can I initialize a individual structure variable as follows:

    struct my
    {
        int a;
        int b = 4;
    };
    
A: 

Question 1: I think the variable declared in the local scope takes precidence, it shouldn't overwrite it but in the scope that the variable is declared it will be used instead.

That is assuming that it compiles.

Omar Kooheji
+7  A: 

Question 1

All references to ref_buf in that function will bind to the parameter and not the global variable.

Question 2

This is not legal in C but is legal in C++. The keyword static in C can only be used on file scope variables or on locals.

Question 3

No this is not legal in C (or C++). You will need to create a factory method to handle this.

my create_my() {
  my m;
  m.b = 4;
  return m;
}
JaredPar
m = stackoverflow!
BenB
returning the address to a stack variable is a recipe for bad seg-faults...
Trevor Boyd Smith
@Trevor, where am I doing that?
JaredPar
@Trevor Are you reading `return ` instead of what's actually there? Right now it returns a copy.
ephemient
+4  A: 

On Q3: GCC allows you to initialize a struct like this (as required by the C99 standard):

struct
{
    int a;
    int b;
} my = { .b = 4 };

GCC doc on designated initializers

diciu
+1, can you add a link to the reference on this feature?
JaredPar
I've added a link - I don't really use these but they are popular in networking code that's full of unions and struct.
diciu
In pre-C99, and C++, you can write `struct ... my = {0, 4};`, providing initializers in order. C99's designated initializers are much nicer, though.
ephemient
A: 
Dale
A: 
  1. Yes, it will technically overwrite, but a good compiler will warn you about this situation, and you will have "warnings = errors" on when you compile, so this won't actually compile.

  2. Not needed, since the "my" struct is already declared as static, and it is therefore declared for the entire struct. This allocates the memory for the entire struct, so there is no need to say "take part of the struct which is already static and make it static".

  3. No, not in the definition, but you can when you create an "instance", something like:

    struct my MY = { {0, 4} };

BenB
A: 

On Q1:

Do not declare variables in a header file. If you include that header file in two source files and compile the source files together, you've got problems. Maybe your linker will get you out of them, maybe not.

If you really need global variables, and this happens a lot less than typical beginners think, put something like extern int ref_buf; in the header file, and int ref_buf; in a source file. That means there is one ref_buf, and all other source files will be able to find it.

The function parameter is essentially a new variable with the same name, and all references in the function will be to it. You will not be able to access the global variable from within that function. The function creates an inner scope, and variables declared in an inner scope are different from those in an outer one. This is potentially confusing, and makes it easy to create bugs, so having variables of the same name and different scopes is generally discouraged. (Variables of the same name in different struct definitions are usually not confusing, since you have to specify what struct contains the variable.)

The compiler will compile the function, but a good compiler will issue a warning message. If it refuses to compile because of one variable shadowing another of the same name, it isn't a real C compiler.

David Thornley
+1  A: 

1a) The local and global variables are separate entities, and so the local one won't overwrite the global. However, the global one won't be accessible inside the function (see also notes below).

1b) It not actually incorrect, but it is guaranteed to cause confusion, and confusion causes bugs, so it's best to use different names for each.

2) No, that's not legal C. You can however make the whole struct static.

3) No. You do it like this:

struct my
{
    int a;
    int b;
} = {0, 4};


Note 1: Variables should be declared in .c files, not .h files. If you need to make a variable accessible in multiple files, put an extern declaration in the header file.

Note 2: Avoid global variables if at all possible.

Steve Melnikoff