Argument 'sample2' conceals a global declaration of the same symbol - c

I have a weird problem in C. I have a structure and I pointed sample to that structure :
test sample;
now in the code, I call that structure through a function :
function is called something, so something(&sample) is used to point the structure in the function.
Now I need to copy values of sample to sample2 .. So I want sample2 to point to the same structure as well. So I also declared test sample2 before main, and used it as a global variable. Now when its used to point to contents in the structure in the function, sample must be called without a (*sample2).content or sample2->content. I only need to write sample2.content. I understand that this happens because sample2 declared globally... But I also get this when compiling :
comment 528 - Argument 'sample2' conceals a global declaration of the same symbol
The program runs fine, but I want to get rid of this compiler message... Why does it say that ? what does it mean ?

The issue is that inside the function if you refer to the symbol sample the compiler has two things to choose from. The first is the global variable and the second is the argument you provided to the function. What the compiler is doing is alerting you to the fact that it assumes you mean the local variable and not the global one.
In general this is a recipe for grief and bugs, and you say that your code runs as intended. I cannot say how or why without looking at it in detail. The simplest answer is to just change the name of the argument to your function to something different or the global variable to something different.

Without seeing the code I can't be sure...
But it sounds like you have a function which is taking a 'test' which you have called 'sample2', by doing that it means you can't access the sample2 you defined globally.
Placing the code in your question would be useful.

Actually, you have to use the dot (.) member selector rather than
the arrow (->) member selector because sample is a struct, rather
than a pointer to a struct. Which has nothing to do with the error message you receive;
My guess (since I can't see your code) is that you pass sample2 as an argument to a function. This sample2 is a different sample2 than the structure you've declared globally. Since they have the same name, you will only be able to use the argument in that function, and not the global sample2.
Please consider editing your question and posting your entire code for review. There are a lot of strange assumptions in your question, and it's possible that you're relying on more than one misunderstanding.

Related

Is there a syntax error in this function declaration?

This is from a textbook:
/* This function locates the address of where a new structure
should be inserted within an existing list.
It receives the address of a name and returns the address of a
structure of type NameRec
*/
struct NameRec *linear Locate(char *name)
{
...
}
I understand it returns a pointer to a struct NameRec. Why is "linear" there and why is there a space between "linear" and "Locate"?
#define linear
will make it syntactically correct even if it wasn't before (though, technically, you'd probably want a #undef linear beforehand to avoid possible conflicting macro definitions).
It depends entirely on the context of the code, which you haven't shown. As it stands now, with no header inclusions or definitions like -Dlinear= on the compiler command line, it would not compile in a standards-conformant environment without extensions.
The best way to tell, of course, is to just try to actually compile the thing and see what happens :-)
Given that the solutions link for chapter 13 (the one you're asking about) has no mention of the linear word in the solution, I'd say it's a safe bet to assume your book is incorrect. I'd consider contacting the author (apparently currently working at FDU in New Jersey) to clear it up.
It's a typo in the book. See the locate function here:
https://users.ipfw.edu/chansavj/ACY2017/ANSI_C/ANSI_C_4thEd/Solutions%20to%20Exercises%20(Windows)/Solutions/83556-0s/Ch13/pgm13-5ex3.c
(Posted by ta.speot.is in the comments)

Do gcc function attributes affect function pointers?

Do gcc's function attributes extensions have any effect when used on the type of function pointers?
The function attributes can be used when declaring the type of function pointers but at least some of them seem to have no effect.
https://stackoverflow.com/a/28740576/1128289
The gcc documentation itself does not address this issue.
Very generally, the C standard basically says that handling an object over a pointer whose type is not aligned with the type of the object itself generates undefined behaviour - There are many exceptions to this general rule, but, apparently, none of them seems to apply to your case.
That means we're moving on very unsafe grounds here, in the first place.
First, you need to distinguish function attributes into two classes:
Function attributes that actually change something in the behavior or location of the function itself like aligned or interrupt- A function that is not attributed that way will not change its inner code once you declare a pointer to it interrupt, for example (the code that is generated for the function would need to dynamically change - for example, a "return from interrupt" instruction replaced by a "return normally" one - depending on along what type of pointer it would have been called). This is obviously not possible.
Function attributes that tell the calling code something about the behaviour that can be expected from the function - like noreturn or malloc, for example. Those attributes sometimes might not modify the function code itself (you'll never know, however...), but rather tell the calling code something about assumptions it can make in order to optimise. These assumptions will affect the calling function only and thus can be triggered by tweaking a pointer (you don't even need a pointer to do that, a modified function prototype should suffice - for the language, that would actually turn out to have the same effect). If you tell the compiler it can make such assumptions and those turn out not to be true, this will, however, lead to all sorts of things go wrong. After all, C makes the programmer responsible for making sure a pointer points to the right type of thing.
There are, however, function attributes that actually restrict the amount of assumptions a calling function would be allowed to make (the most obvious would be malloc that tells calling code it returns yet untyped and uninitialized memory). Those should be relatively safe to use (I do, however, fail to come up with a use case atm)
Without very detailed knowledge on what belongs into (1) or (2) above, and what exactly a function attribute might affect in both called and calling code (which would be very difficult to achieve, because I don't recall to ever have seen that documented in detail), you thus will not be able to decide whether this pointer tweaking actually is possible and what side effects it might generate.
Also, in my opinion, there is not much of a difference between tweaking a pointer to a function and calling an external function with a (deliberately) wrong prototype. This might give you some insight on what you are actually trying to do...

C: static int gets strange value

(changed name of variable from original question to fit the actual code)
I'm new to C and I'm implementing a queue.
The error is with the static int head=0 variable. It's incremented by 1 each time dequeue() is called. The error seem to occur when the queue is dequeued and function get_person() is called. The head-variable is then as it seems getting a high random number, like 23423449. I have no idea where this comes from. However if I get rid of the "static" keyword so variable is declared as int head=0, it works fine. How come?
using a "global" variable in top of a included file: static int variable1=0
This clearly indicates, that you don't understand what the static keyword means on the global scope. In the global scope, outside of a function, static means, that the variable is visible to only the code within the compilation unit the variable has been defined in.
Now if you define a static variable in a header, each compilation unit that includes that header will have its own variable of that name. So your program is littered with many identically named variables each specific to the compilation unit it's in.
I think what you actually want is an non-static, extern declaration in the header, and exactly one compilation unit actually defining the variable.
I think you are overrunning your person array
One of the strcpy functions is going beyond the bounds of the buffers in the person object, and overwriting the head variable. I would guess the tail and nbr_elem are going too.
You should check that the number of characters you are copying does not exceed the buffer lengths, or use strncpy.
If you declare a global static variable in file A.c, it means this variable is only available within the scope of this A.c file. See : http://en.wikipedia.org/wiki/Static_variable
Since you haven't posted any code, and you are metioning using the same variable in a different file (e.g. B.c), it seems like it is invoking an undefined behavior, which explains the random number your program is printing.
If you wish to use the variable in a different .c file, you should not make it static.
You are calling strcpy without checking that the values you are trying to write will actually fit inside the allocated space inside the person struct.
What is most likely happening is you are writing beyond the allocated memory, and your strcpy is actually overwriting the value of head. strcpy will keep writing until it hits a null terminator ('\0').
If you were to run this in valgrind (a useful tool for finding this type of problem in large programs) it would probably tell you you have invalid writes occurring.
C assumes you know what you are doing, as long as you have access to the memory you can do with it as you please :)

Can I detect the existence of a local variable inside a macro?

Is there a way to safely check to see whether some named variable (let's call it "foo") is present in the current scope? I'd like to have a macro that, say, makes use of "foo" if it's present, otherwise does something else. Are there any runtime tricks I can make use of here?
(The actual context is trying to solve this problem, but I realized that one could be a special case of this one, so a separate question seemed also interesting.)
Unfortunately, no. The compiler is responsible for parsing variable names and assigning scopes to them, and the preprocessor runs before the compiler. So it has no access to that information.

How to initialize a header-only global variable in C

I have a function defined in a header-only library that looks like this:
inline bar **foo_ptr() {
static bar *value = NULL;
return &value;
}
This is my hackish way of initializing a global variable without defining it in a *.c file.
This compiles fine in VS2010 (after a #define inline __inline), but dies in an angry fit of multiple definition rage upon any attempt to compile it in MinGW. This is making me Very Sad.
AFAIK, I can't just use a static inline function, as it would create multiple occurrences of value, which, for this situation, is a Very Bad Thing.
What keyword(s) should I really be using in order to make this work? Am I going at it completely wrong? Is there an alternative way to initialize a header-only global variable to NULL?
I would prefer to stay away from init methods.
Thanks :D
The C99 standard says in section §6.7.4 Function specifiers:
¶2 An inline definition of a function with external linkage shall not contain a definition of a
modifiable object with static storage duration, and shall not contain a reference to an
identifier with internal linkage.
Your function is currently trying to return a pointer to a local variable; that is a well-known no-no. But the standard prohibits you from changing that variable into a static. If there was an external variable value, then it could be made to work, sort of. But it probably defeats the objective you were trying to achieve:
extern bar *value;
inline bar **foo_ptr() {
value = NULL;
return &value;
}
But the variable must be declared, so it is accessible. It must also be defined somewhere. Frankly, you'll be better off just accepting that if you need a global variable, it is best to use (declare, define) one.
Well, I'm gonna answer my own question here, but credit all goes to Jason Coco (if you feel like making your own answer I'll gladly accept that instead).
Anyways - the solution was to simply declare the global variable without initializing it. The compiler would automatically set it to null.
bar *foo;
Problem solved :)

Resources