Scope of function prototypes in c file instead of header
Apologies if this question has been asked before (I only found variants to this question on SO, but not the exact one)
My question is regarding scope w.r.t where the function prototype is defined.
Assume we have 3 files : test.h
, test.c
, main.c
main.c
and test.c
both includes test.h
test.c:
int f2(int b); // function prototype (local)
int x=0;
// public function
int f1(int a){
return a*5;
}
// local function
int f2(int b){
return b*10;
}
test.h:
int f1(int a);
main.c:
#include "test.h"
int x=1;
int main(){
printf("%d n", f1(5));
printf("%d n", f2(5));
return 0;
}
My question is:
- Can
main.c
accessf2()
which is implemented and prototype declared insidetest.c
- Can
main.c
accessf1()
? or does it need to be declared asextern
- Does
main.c
have access to thex
global variable insidetest.c
? Will it conflict with the global variablex
(same name) defined inmain.c
? - To gain local scope is it mandatory to use
static
keyword? - Can static functions access global variables (static/non-static) defined in the same
.c
file ?
c scope
add a comment |
Apologies if this question has been asked before (I only found variants to this question on SO, but not the exact one)
My question is regarding scope w.r.t where the function prototype is defined.
Assume we have 3 files : test.h
, test.c
, main.c
main.c
and test.c
both includes test.h
test.c:
int f2(int b); // function prototype (local)
int x=0;
// public function
int f1(int a){
return a*5;
}
// local function
int f2(int b){
return b*10;
}
test.h:
int f1(int a);
main.c:
#include "test.h"
int x=1;
int main(){
printf("%d n", f1(5));
printf("%d n", f2(5));
return 0;
}
My question is:
- Can
main.c
accessf2()
which is implemented and prototype declared insidetest.c
- Can
main.c
accessf1()
? or does it need to be declared asextern
- Does
main.c
have access to thex
global variable insidetest.c
? Will it conflict with the global variablex
(same name) defined inmain.c
? - To gain local scope is it mandatory to use
static
keyword? - Can static functions access global variables (static/non-static) defined in the same
.c
file ?
c scope
add a comment |
Apologies if this question has been asked before (I only found variants to this question on SO, but not the exact one)
My question is regarding scope w.r.t where the function prototype is defined.
Assume we have 3 files : test.h
, test.c
, main.c
main.c
and test.c
both includes test.h
test.c:
int f2(int b); // function prototype (local)
int x=0;
// public function
int f1(int a){
return a*5;
}
// local function
int f2(int b){
return b*10;
}
test.h:
int f1(int a);
main.c:
#include "test.h"
int x=1;
int main(){
printf("%d n", f1(5));
printf("%d n", f2(5));
return 0;
}
My question is:
- Can
main.c
accessf2()
which is implemented and prototype declared insidetest.c
- Can
main.c
accessf1()
? or does it need to be declared asextern
- Does
main.c
have access to thex
global variable insidetest.c
? Will it conflict with the global variablex
(same name) defined inmain.c
? - To gain local scope is it mandatory to use
static
keyword? - Can static functions access global variables (static/non-static) defined in the same
.c
file ?
c scope
Apologies if this question has been asked before (I only found variants to this question on SO, but not the exact one)
My question is regarding scope w.r.t where the function prototype is defined.
Assume we have 3 files : test.h
, test.c
, main.c
main.c
and test.c
both includes test.h
test.c:
int f2(int b); // function prototype (local)
int x=0;
// public function
int f1(int a){
return a*5;
}
// local function
int f2(int b){
return b*10;
}
test.h:
int f1(int a);
main.c:
#include "test.h"
int x=1;
int main(){
printf("%d n", f1(5));
printf("%d n", f2(5));
return 0;
}
My question is:
- Can
main.c
accessf2()
which is implemented and prototype declared insidetest.c
- Can
main.c
accessf1()
? or does it need to be declared asextern
- Does
main.c
have access to thex
global variable insidetest.c
? Will it conflict with the global variablex
(same name) defined inmain.c
? - To gain local scope is it mandatory to use
static
keyword? - Can static functions access global variables (static/non-static) defined in the same
.c
file ?
c scope
c scope
edited Nov 22 '18 at 1:45
Rosh
asked Nov 21 '18 at 5:31
RoshRosh
214
214
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
In answering your questions, I suppose that the two .c sources are compiled and linked together into one program.
- Can
main.c
accessf2()
which is implemented and prototype declared insidetest2.c
Modern C does not permit calls to functions that have no declaration in scope, but K&R C did permit such calls, and most implementations do still allow them. Moreover, main.c
could declare the function itself and then call it.
- Can
main.c
accessf1()
? or does it need to be declared asextern
Functions have external linkage by default. Accordingly, extern
is the default for function declarations. You may explicitly specify extern
, but that's redundant.
- Does
main.c
have access to thex
global variable insidetest.c
? Will it conflict with the global variablex
(same name) defined in
main.c?
Yes and no. It is erroneous for one program to contain two definitions of the same identifier with external linkage, and both your declarations of x
do indeed constitute definitions, and both do indeed (by default) have external linkage.
However, some implementations will merge those into one variable, others will refuse to link the program, and others might even maintain separate x
variables.
The right way to declare a variable that is shared across source files, by the way, is for each file to declare it, extern
, but for exactly one to initialize it. Usually, the extern
declarations without initializer would go into a header file, and a single declaration with an initializer (which makes it a definition) would go into one .c file. Example:
test.h
extern int x; // _with_ extern, _without_ initializer
test.c
#include "test.h"
int x = 0; // 'extern' is optional here
main.c
#include "test.h"
// no further declaration of x here
- To gain local scope is it mandatory to use
static
keyword?
The static
and extern
keywords are about linkage, not scope. Linkage has to do with which code can access which objects and functions. Scope is about which code can see which declarations. Although they sound similar, these are in fact quite distinct concepts, because the same object or function can be declared multiple times. In fact, that's routine -- it's one of the primary purposes served by header files.
- Can static functions access global variables (static/non-static) defined in the same
.c
file ?
Yes, where I interpret "global" to mean "declared at file scope". C does not have a concept of global variables per se, but objects declared outside any function exist for the whole duration of the program. Those with external linkage can be accessed from any code in the program where declarations of their identifiers are in scope. Those with internal linkage (declared by the static
keyword) can be accessed only from within the same translation unit, which roughly means the same .c file.
It is also possible for an object to have no linkage. This is the case for objects declared inside functions.
I understand the answer is compiler/linker specific. I'm compiling for the MSP430 platform, so assume the msp-gcc compiler (C89). But I would like to know the behaviour latest standard GCC compiler and Gnu tools (assuming set to C89). So for the first question - if i compile and run the above, will it produce a compiler/linker/runtime error/warning ?
– Rosh
Nov 22 '18 at 1:53
@Rosh, if what you are taking away is that the answer is compiler-specific, then you are missing the point: write conforming code, so that its behavior is not compiler specific. It is not that hard to do. As for GCC's behavior with respect to any of these questions, have you not considered trying it out for yourself? It turns out, though, that GCC is among the compilers that still accepts implicit function declarations. It will emit a warning about them under many combinations of options, and if you wish, you can cause that to be emitted as an error instead.
– John Bollinger
Nov 22 '18 at 4:10
add a comment |
1) Yes, but accidentally. A function with no declarator will default to int
type, and its parameters will default to int
type, and storage class will default to extern
. Your function happens to already have those types. Thus, the declarator is not needed, strictly speaking (though it is a very bad practice to not use one). However, this has apparently been made illegal in C99, and if you are using C99 semantics, you should get an error; otherwise it is just a warning (-Wimplicit-function-declaration
).
2) As said above, the lack of storage class specifier in the test.h
declarator will implicitly declare f1
as extern. All is well.
3) The linker will raise an error regarding duplicate identifier. If you use extern int x;
(with no initialisation), it works. Variables don't get implicit declarations; if you just attempt to use x
in main.c
without the above declaration, you will get an error regarding use of an undeclared variable.
4) static
means several different things. I assume the question is about static functions. This only restricts the visibility of the function to the current compilation unit; there is no other effect.
5) As noted above, making a function static only affects what can access it, not what it can access.
1
In strict C99 or later, functions do not default to anything; they must be declared (or defined) before they are used.
– Jonathan Leffler
Nov 21 '18 at 5:52
I think i'm more interested in C89 behaviour, but thanks for the info.
– Rosh
Nov 22 '18 at 1:56
add a comment |
Can main.c access f2() which is implemented and prototype declared inside test2.c
The function f2
will be taken as a default function which has return value of int and parameters int
if any. However, if you use different parameters, it will give an error.
From C99 onwards, the default function is not applicable and this will give an error.
Can main.c access f1()? or does it need to be declared as extern
Yes, it can access f1() as you have included test.h
However you also need to compile test.c
and give both files to the linker.
f1()
declaration in test.h
does not need to be declared as extern. By default, a function declaration is extern.
Does main.c have access to the x global variable inside test.c? Will it conflict with the global variable x (same name) defined in main.c?
You need to link the variables together. Once you do you will get a linker error for this.
To gain local scope is it mandatory to use static keyword?
If the variable is declared outside a function, it is global. To make it local scope you need to specifically use the static keyword.
Can static functions access global variables (static/non-static) defined in the same .c file ?
Yes
In C90, the assumed return type of a function was indeedint
, but nothing was assumed about the arguments except that they were subject to default argument promotion rules. C99 and above does not, strictly, allow functions to be used before they are declared (or defined).
– Jonathan Leffler
Nov 21 '18 at 7:23
So, in practice anint
orint, int
orchar
argument is OK, but notfloat
– Rishikesh Raje
Nov 21 '18 at 7:29
Nope. Afloat
will be promoted todouble
, that's all. You can passchar *
andstruct Anything *
and so on too. Further, the compiler isn't required to check your calls for consistency. If you use an explicit function declaration likeextern int function();
then that has no prototype and any arguments are default promoted and there's no guarantee the compiler will cross-check different calls for consistency. The C99 rules require a declaration; they don't require a prototype declaration, though. You should tell your compiler to require strict prototype declarations if possible.
– Jonathan Leffler
Nov 21 '18 at 7:32
Hi, so I don't understand the first answer. what is a 'default function' ? My question is if main() can call f2(), even though it can't see the function declaration, as it's not in the test.h header file. will this return a compiler / linker / runtime error/warning ?
– Rosh
Nov 22 '18 at 1:48
@Rosh - In C89 and before, if there was no declaration the compiler would implicitly assume that the function will return anint
. A warning may be given based on your flags.
– Rishikesh Raje
Nov 22 '18 at 4:05
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53405773%2fscope-of-function-prototypes-in-c-file-instead-of-header%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
In answering your questions, I suppose that the two .c sources are compiled and linked together into one program.
- Can
main.c
accessf2()
which is implemented and prototype declared insidetest2.c
Modern C does not permit calls to functions that have no declaration in scope, but K&R C did permit such calls, and most implementations do still allow them. Moreover, main.c
could declare the function itself and then call it.
- Can
main.c
accessf1()
? or does it need to be declared asextern
Functions have external linkage by default. Accordingly, extern
is the default for function declarations. You may explicitly specify extern
, but that's redundant.
- Does
main.c
have access to thex
global variable insidetest.c
? Will it conflict with the global variablex
(same name) defined in
main.c?
Yes and no. It is erroneous for one program to contain two definitions of the same identifier with external linkage, and both your declarations of x
do indeed constitute definitions, and both do indeed (by default) have external linkage.
However, some implementations will merge those into one variable, others will refuse to link the program, and others might even maintain separate x
variables.
The right way to declare a variable that is shared across source files, by the way, is for each file to declare it, extern
, but for exactly one to initialize it. Usually, the extern
declarations without initializer would go into a header file, and a single declaration with an initializer (which makes it a definition) would go into one .c file. Example:
test.h
extern int x; // _with_ extern, _without_ initializer
test.c
#include "test.h"
int x = 0; // 'extern' is optional here
main.c
#include "test.h"
// no further declaration of x here
- To gain local scope is it mandatory to use
static
keyword?
The static
and extern
keywords are about linkage, not scope. Linkage has to do with which code can access which objects and functions. Scope is about which code can see which declarations. Although they sound similar, these are in fact quite distinct concepts, because the same object or function can be declared multiple times. In fact, that's routine -- it's one of the primary purposes served by header files.
- Can static functions access global variables (static/non-static) defined in the same
.c
file ?
Yes, where I interpret "global" to mean "declared at file scope". C does not have a concept of global variables per se, but objects declared outside any function exist for the whole duration of the program. Those with external linkage can be accessed from any code in the program where declarations of their identifiers are in scope. Those with internal linkage (declared by the static
keyword) can be accessed only from within the same translation unit, which roughly means the same .c file.
It is also possible for an object to have no linkage. This is the case for objects declared inside functions.
I understand the answer is compiler/linker specific. I'm compiling for the MSP430 platform, so assume the msp-gcc compiler (C89). But I would like to know the behaviour latest standard GCC compiler and Gnu tools (assuming set to C89). So for the first question - if i compile and run the above, will it produce a compiler/linker/runtime error/warning ?
– Rosh
Nov 22 '18 at 1:53
@Rosh, if what you are taking away is that the answer is compiler-specific, then you are missing the point: write conforming code, so that its behavior is not compiler specific. It is not that hard to do. As for GCC's behavior with respect to any of these questions, have you not considered trying it out for yourself? It turns out, though, that GCC is among the compilers that still accepts implicit function declarations. It will emit a warning about them under many combinations of options, and if you wish, you can cause that to be emitted as an error instead.
– John Bollinger
Nov 22 '18 at 4:10
add a comment |
In answering your questions, I suppose that the two .c sources are compiled and linked together into one program.
- Can
main.c
accessf2()
which is implemented and prototype declared insidetest2.c
Modern C does not permit calls to functions that have no declaration in scope, but K&R C did permit such calls, and most implementations do still allow them. Moreover, main.c
could declare the function itself and then call it.
- Can
main.c
accessf1()
? or does it need to be declared asextern
Functions have external linkage by default. Accordingly, extern
is the default for function declarations. You may explicitly specify extern
, but that's redundant.
- Does
main.c
have access to thex
global variable insidetest.c
? Will it conflict with the global variablex
(same name) defined in
main.c?
Yes and no. It is erroneous for one program to contain two definitions of the same identifier with external linkage, and both your declarations of x
do indeed constitute definitions, and both do indeed (by default) have external linkage.
However, some implementations will merge those into one variable, others will refuse to link the program, and others might even maintain separate x
variables.
The right way to declare a variable that is shared across source files, by the way, is for each file to declare it, extern
, but for exactly one to initialize it. Usually, the extern
declarations without initializer would go into a header file, and a single declaration with an initializer (which makes it a definition) would go into one .c file. Example:
test.h
extern int x; // _with_ extern, _without_ initializer
test.c
#include "test.h"
int x = 0; // 'extern' is optional here
main.c
#include "test.h"
// no further declaration of x here
- To gain local scope is it mandatory to use
static
keyword?
The static
and extern
keywords are about linkage, not scope. Linkage has to do with which code can access which objects and functions. Scope is about which code can see which declarations. Although they sound similar, these are in fact quite distinct concepts, because the same object or function can be declared multiple times. In fact, that's routine -- it's one of the primary purposes served by header files.
- Can static functions access global variables (static/non-static) defined in the same
.c
file ?
Yes, where I interpret "global" to mean "declared at file scope". C does not have a concept of global variables per se, but objects declared outside any function exist for the whole duration of the program. Those with external linkage can be accessed from any code in the program where declarations of their identifiers are in scope. Those with internal linkage (declared by the static
keyword) can be accessed only from within the same translation unit, which roughly means the same .c file.
It is also possible for an object to have no linkage. This is the case for objects declared inside functions.
I understand the answer is compiler/linker specific. I'm compiling for the MSP430 platform, so assume the msp-gcc compiler (C89). But I would like to know the behaviour latest standard GCC compiler and Gnu tools (assuming set to C89). So for the first question - if i compile and run the above, will it produce a compiler/linker/runtime error/warning ?
– Rosh
Nov 22 '18 at 1:53
@Rosh, if what you are taking away is that the answer is compiler-specific, then you are missing the point: write conforming code, so that its behavior is not compiler specific. It is not that hard to do. As for GCC's behavior with respect to any of these questions, have you not considered trying it out for yourself? It turns out, though, that GCC is among the compilers that still accepts implicit function declarations. It will emit a warning about them under many combinations of options, and if you wish, you can cause that to be emitted as an error instead.
– John Bollinger
Nov 22 '18 at 4:10
add a comment |
In answering your questions, I suppose that the two .c sources are compiled and linked together into one program.
- Can
main.c
accessf2()
which is implemented and prototype declared insidetest2.c
Modern C does not permit calls to functions that have no declaration in scope, but K&R C did permit such calls, and most implementations do still allow them. Moreover, main.c
could declare the function itself and then call it.
- Can
main.c
accessf1()
? or does it need to be declared asextern
Functions have external linkage by default. Accordingly, extern
is the default for function declarations. You may explicitly specify extern
, but that's redundant.
- Does
main.c
have access to thex
global variable insidetest.c
? Will it conflict with the global variablex
(same name) defined in
main.c?
Yes and no. It is erroneous for one program to contain two definitions of the same identifier with external linkage, and both your declarations of x
do indeed constitute definitions, and both do indeed (by default) have external linkage.
However, some implementations will merge those into one variable, others will refuse to link the program, and others might even maintain separate x
variables.
The right way to declare a variable that is shared across source files, by the way, is for each file to declare it, extern
, but for exactly one to initialize it. Usually, the extern
declarations without initializer would go into a header file, and a single declaration with an initializer (which makes it a definition) would go into one .c file. Example:
test.h
extern int x; // _with_ extern, _without_ initializer
test.c
#include "test.h"
int x = 0; // 'extern' is optional here
main.c
#include "test.h"
// no further declaration of x here
- To gain local scope is it mandatory to use
static
keyword?
The static
and extern
keywords are about linkage, not scope. Linkage has to do with which code can access which objects and functions. Scope is about which code can see which declarations. Although they sound similar, these are in fact quite distinct concepts, because the same object or function can be declared multiple times. In fact, that's routine -- it's one of the primary purposes served by header files.
- Can static functions access global variables (static/non-static) defined in the same
.c
file ?
Yes, where I interpret "global" to mean "declared at file scope". C does not have a concept of global variables per se, but objects declared outside any function exist for the whole duration of the program. Those with external linkage can be accessed from any code in the program where declarations of their identifiers are in scope. Those with internal linkage (declared by the static
keyword) can be accessed only from within the same translation unit, which roughly means the same .c file.
It is also possible for an object to have no linkage. This is the case for objects declared inside functions.
In answering your questions, I suppose that the two .c sources are compiled and linked together into one program.
- Can
main.c
accessf2()
which is implemented and prototype declared insidetest2.c
Modern C does not permit calls to functions that have no declaration in scope, but K&R C did permit such calls, and most implementations do still allow them. Moreover, main.c
could declare the function itself and then call it.
- Can
main.c
accessf1()
? or does it need to be declared asextern
Functions have external linkage by default. Accordingly, extern
is the default for function declarations. You may explicitly specify extern
, but that's redundant.
- Does
main.c
have access to thex
global variable insidetest.c
? Will it conflict with the global variablex
(same name) defined in
main.c?
Yes and no. It is erroneous for one program to contain two definitions of the same identifier with external linkage, and both your declarations of x
do indeed constitute definitions, and both do indeed (by default) have external linkage.
However, some implementations will merge those into one variable, others will refuse to link the program, and others might even maintain separate x
variables.
The right way to declare a variable that is shared across source files, by the way, is for each file to declare it, extern
, but for exactly one to initialize it. Usually, the extern
declarations without initializer would go into a header file, and a single declaration with an initializer (which makes it a definition) would go into one .c file. Example:
test.h
extern int x; // _with_ extern, _without_ initializer
test.c
#include "test.h"
int x = 0; // 'extern' is optional here
main.c
#include "test.h"
// no further declaration of x here
- To gain local scope is it mandatory to use
static
keyword?
The static
and extern
keywords are about linkage, not scope. Linkage has to do with which code can access which objects and functions. Scope is about which code can see which declarations. Although they sound similar, these are in fact quite distinct concepts, because the same object or function can be declared multiple times. In fact, that's routine -- it's one of the primary purposes served by header files.
- Can static functions access global variables (static/non-static) defined in the same
.c
file ?
Yes, where I interpret "global" to mean "declared at file scope". C does not have a concept of global variables per se, but objects declared outside any function exist for the whole duration of the program. Those with external linkage can be accessed from any code in the program where declarations of their identifiers are in scope. Those with internal linkage (declared by the static
keyword) can be accessed only from within the same translation unit, which roughly means the same .c file.
It is also possible for an object to have no linkage. This is the case for objects declared inside functions.
edited Nov 21 '18 at 6:20
answered Nov 21 '18 at 6:08
John BollingerJohn Bollinger
83k74279
83k74279
I understand the answer is compiler/linker specific. I'm compiling for the MSP430 platform, so assume the msp-gcc compiler (C89). But I would like to know the behaviour latest standard GCC compiler and Gnu tools (assuming set to C89). So for the first question - if i compile and run the above, will it produce a compiler/linker/runtime error/warning ?
– Rosh
Nov 22 '18 at 1:53
@Rosh, if what you are taking away is that the answer is compiler-specific, then you are missing the point: write conforming code, so that its behavior is not compiler specific. It is not that hard to do. As for GCC's behavior with respect to any of these questions, have you not considered trying it out for yourself? It turns out, though, that GCC is among the compilers that still accepts implicit function declarations. It will emit a warning about them under many combinations of options, and if you wish, you can cause that to be emitted as an error instead.
– John Bollinger
Nov 22 '18 at 4:10
add a comment |
I understand the answer is compiler/linker specific. I'm compiling for the MSP430 platform, so assume the msp-gcc compiler (C89). But I would like to know the behaviour latest standard GCC compiler and Gnu tools (assuming set to C89). So for the first question - if i compile and run the above, will it produce a compiler/linker/runtime error/warning ?
– Rosh
Nov 22 '18 at 1:53
@Rosh, if what you are taking away is that the answer is compiler-specific, then you are missing the point: write conforming code, so that its behavior is not compiler specific. It is not that hard to do. As for GCC's behavior with respect to any of these questions, have you not considered trying it out for yourself? It turns out, though, that GCC is among the compilers that still accepts implicit function declarations. It will emit a warning about them under many combinations of options, and if you wish, you can cause that to be emitted as an error instead.
– John Bollinger
Nov 22 '18 at 4:10
I understand the answer is compiler/linker specific. I'm compiling for the MSP430 platform, so assume the msp-gcc compiler (C89). But I would like to know the behaviour latest standard GCC compiler and Gnu tools (assuming set to C89). So for the first question - if i compile and run the above, will it produce a compiler/linker/runtime error/warning ?
– Rosh
Nov 22 '18 at 1:53
I understand the answer is compiler/linker specific. I'm compiling for the MSP430 platform, so assume the msp-gcc compiler (C89). But I would like to know the behaviour latest standard GCC compiler and Gnu tools (assuming set to C89). So for the first question - if i compile and run the above, will it produce a compiler/linker/runtime error/warning ?
– Rosh
Nov 22 '18 at 1:53
@Rosh, if what you are taking away is that the answer is compiler-specific, then you are missing the point: write conforming code, so that its behavior is not compiler specific. It is not that hard to do. As for GCC's behavior with respect to any of these questions, have you not considered trying it out for yourself? It turns out, though, that GCC is among the compilers that still accepts implicit function declarations. It will emit a warning about them under many combinations of options, and if you wish, you can cause that to be emitted as an error instead.
– John Bollinger
Nov 22 '18 at 4:10
@Rosh, if what you are taking away is that the answer is compiler-specific, then you are missing the point: write conforming code, so that its behavior is not compiler specific. It is not that hard to do. As for GCC's behavior with respect to any of these questions, have you not considered trying it out for yourself? It turns out, though, that GCC is among the compilers that still accepts implicit function declarations. It will emit a warning about them under many combinations of options, and if you wish, you can cause that to be emitted as an error instead.
– John Bollinger
Nov 22 '18 at 4:10
add a comment |
1) Yes, but accidentally. A function with no declarator will default to int
type, and its parameters will default to int
type, and storage class will default to extern
. Your function happens to already have those types. Thus, the declarator is not needed, strictly speaking (though it is a very bad practice to not use one). However, this has apparently been made illegal in C99, and if you are using C99 semantics, you should get an error; otherwise it is just a warning (-Wimplicit-function-declaration
).
2) As said above, the lack of storage class specifier in the test.h
declarator will implicitly declare f1
as extern. All is well.
3) The linker will raise an error regarding duplicate identifier. If you use extern int x;
(with no initialisation), it works. Variables don't get implicit declarations; if you just attempt to use x
in main.c
without the above declaration, you will get an error regarding use of an undeclared variable.
4) static
means several different things. I assume the question is about static functions. This only restricts the visibility of the function to the current compilation unit; there is no other effect.
5) As noted above, making a function static only affects what can access it, not what it can access.
1
In strict C99 or later, functions do not default to anything; they must be declared (or defined) before they are used.
– Jonathan Leffler
Nov 21 '18 at 5:52
I think i'm more interested in C89 behaviour, but thanks for the info.
– Rosh
Nov 22 '18 at 1:56
add a comment |
1) Yes, but accidentally. A function with no declarator will default to int
type, and its parameters will default to int
type, and storage class will default to extern
. Your function happens to already have those types. Thus, the declarator is not needed, strictly speaking (though it is a very bad practice to not use one). However, this has apparently been made illegal in C99, and if you are using C99 semantics, you should get an error; otherwise it is just a warning (-Wimplicit-function-declaration
).
2) As said above, the lack of storage class specifier in the test.h
declarator will implicitly declare f1
as extern. All is well.
3) The linker will raise an error regarding duplicate identifier. If you use extern int x;
(with no initialisation), it works. Variables don't get implicit declarations; if you just attempt to use x
in main.c
without the above declaration, you will get an error regarding use of an undeclared variable.
4) static
means several different things. I assume the question is about static functions. This only restricts the visibility of the function to the current compilation unit; there is no other effect.
5) As noted above, making a function static only affects what can access it, not what it can access.
1
In strict C99 or later, functions do not default to anything; they must be declared (or defined) before they are used.
– Jonathan Leffler
Nov 21 '18 at 5:52
I think i'm more interested in C89 behaviour, but thanks for the info.
– Rosh
Nov 22 '18 at 1:56
add a comment |
1) Yes, but accidentally. A function with no declarator will default to int
type, and its parameters will default to int
type, and storage class will default to extern
. Your function happens to already have those types. Thus, the declarator is not needed, strictly speaking (though it is a very bad practice to not use one). However, this has apparently been made illegal in C99, and if you are using C99 semantics, you should get an error; otherwise it is just a warning (-Wimplicit-function-declaration
).
2) As said above, the lack of storage class specifier in the test.h
declarator will implicitly declare f1
as extern. All is well.
3) The linker will raise an error regarding duplicate identifier. If you use extern int x;
(with no initialisation), it works. Variables don't get implicit declarations; if you just attempt to use x
in main.c
without the above declaration, you will get an error regarding use of an undeclared variable.
4) static
means several different things. I assume the question is about static functions. This only restricts the visibility of the function to the current compilation unit; there is no other effect.
5) As noted above, making a function static only affects what can access it, not what it can access.
1) Yes, but accidentally. A function with no declarator will default to int
type, and its parameters will default to int
type, and storage class will default to extern
. Your function happens to already have those types. Thus, the declarator is not needed, strictly speaking (though it is a very bad practice to not use one). However, this has apparently been made illegal in C99, and if you are using C99 semantics, you should get an error; otherwise it is just a warning (-Wimplicit-function-declaration
).
2) As said above, the lack of storage class specifier in the test.h
declarator will implicitly declare f1
as extern. All is well.
3) The linker will raise an error regarding duplicate identifier. If you use extern int x;
(with no initialisation), it works. Variables don't get implicit declarations; if you just attempt to use x
in main.c
without the above declaration, you will get an error regarding use of an undeclared variable.
4) static
means several different things. I assume the question is about static functions. This only restricts the visibility of the function to the current compilation unit; there is no other effect.
5) As noted above, making a function static only affects what can access it, not what it can access.
edited Nov 21 '18 at 5:53
answered Nov 21 '18 at 5:49
AmadanAmadan
132k13145197
132k13145197
1
In strict C99 or later, functions do not default to anything; they must be declared (or defined) before they are used.
– Jonathan Leffler
Nov 21 '18 at 5:52
I think i'm more interested in C89 behaviour, but thanks for the info.
– Rosh
Nov 22 '18 at 1:56
add a comment |
1
In strict C99 or later, functions do not default to anything; they must be declared (or defined) before they are used.
– Jonathan Leffler
Nov 21 '18 at 5:52
I think i'm more interested in C89 behaviour, but thanks for the info.
– Rosh
Nov 22 '18 at 1:56
1
1
In strict C99 or later, functions do not default to anything; they must be declared (or defined) before they are used.
– Jonathan Leffler
Nov 21 '18 at 5:52
In strict C99 or later, functions do not default to anything; they must be declared (or defined) before they are used.
– Jonathan Leffler
Nov 21 '18 at 5:52
I think i'm more interested in C89 behaviour, but thanks for the info.
– Rosh
Nov 22 '18 at 1:56
I think i'm more interested in C89 behaviour, but thanks for the info.
– Rosh
Nov 22 '18 at 1:56
add a comment |
Can main.c access f2() which is implemented and prototype declared inside test2.c
The function f2
will be taken as a default function which has return value of int and parameters int
if any. However, if you use different parameters, it will give an error.
From C99 onwards, the default function is not applicable and this will give an error.
Can main.c access f1()? or does it need to be declared as extern
Yes, it can access f1() as you have included test.h
However you also need to compile test.c
and give both files to the linker.
f1()
declaration in test.h
does not need to be declared as extern. By default, a function declaration is extern.
Does main.c have access to the x global variable inside test.c? Will it conflict with the global variable x (same name) defined in main.c?
You need to link the variables together. Once you do you will get a linker error for this.
To gain local scope is it mandatory to use static keyword?
If the variable is declared outside a function, it is global. To make it local scope you need to specifically use the static keyword.
Can static functions access global variables (static/non-static) defined in the same .c file ?
Yes
In C90, the assumed return type of a function was indeedint
, but nothing was assumed about the arguments except that they were subject to default argument promotion rules. C99 and above does not, strictly, allow functions to be used before they are declared (or defined).
– Jonathan Leffler
Nov 21 '18 at 7:23
So, in practice anint
orint, int
orchar
argument is OK, but notfloat
– Rishikesh Raje
Nov 21 '18 at 7:29
Nope. Afloat
will be promoted todouble
, that's all. You can passchar *
andstruct Anything *
and so on too. Further, the compiler isn't required to check your calls for consistency. If you use an explicit function declaration likeextern int function();
then that has no prototype and any arguments are default promoted and there's no guarantee the compiler will cross-check different calls for consistency. The C99 rules require a declaration; they don't require a prototype declaration, though. You should tell your compiler to require strict prototype declarations if possible.
– Jonathan Leffler
Nov 21 '18 at 7:32
Hi, so I don't understand the first answer. what is a 'default function' ? My question is if main() can call f2(), even though it can't see the function declaration, as it's not in the test.h header file. will this return a compiler / linker / runtime error/warning ?
– Rosh
Nov 22 '18 at 1:48
@Rosh - In C89 and before, if there was no declaration the compiler would implicitly assume that the function will return anint
. A warning may be given based on your flags.
– Rishikesh Raje
Nov 22 '18 at 4:05
add a comment |
Can main.c access f2() which is implemented and prototype declared inside test2.c
The function f2
will be taken as a default function which has return value of int and parameters int
if any. However, if you use different parameters, it will give an error.
From C99 onwards, the default function is not applicable and this will give an error.
Can main.c access f1()? or does it need to be declared as extern
Yes, it can access f1() as you have included test.h
However you also need to compile test.c
and give both files to the linker.
f1()
declaration in test.h
does not need to be declared as extern. By default, a function declaration is extern.
Does main.c have access to the x global variable inside test.c? Will it conflict with the global variable x (same name) defined in main.c?
You need to link the variables together. Once you do you will get a linker error for this.
To gain local scope is it mandatory to use static keyword?
If the variable is declared outside a function, it is global. To make it local scope you need to specifically use the static keyword.
Can static functions access global variables (static/non-static) defined in the same .c file ?
Yes
In C90, the assumed return type of a function was indeedint
, but nothing was assumed about the arguments except that they were subject to default argument promotion rules. C99 and above does not, strictly, allow functions to be used before they are declared (or defined).
– Jonathan Leffler
Nov 21 '18 at 7:23
So, in practice anint
orint, int
orchar
argument is OK, but notfloat
– Rishikesh Raje
Nov 21 '18 at 7:29
Nope. Afloat
will be promoted todouble
, that's all. You can passchar *
andstruct Anything *
and so on too. Further, the compiler isn't required to check your calls for consistency. If you use an explicit function declaration likeextern int function();
then that has no prototype and any arguments are default promoted and there's no guarantee the compiler will cross-check different calls for consistency. The C99 rules require a declaration; they don't require a prototype declaration, though. You should tell your compiler to require strict prototype declarations if possible.
– Jonathan Leffler
Nov 21 '18 at 7:32
Hi, so I don't understand the first answer. what is a 'default function' ? My question is if main() can call f2(), even though it can't see the function declaration, as it's not in the test.h header file. will this return a compiler / linker / runtime error/warning ?
– Rosh
Nov 22 '18 at 1:48
@Rosh - In C89 and before, if there was no declaration the compiler would implicitly assume that the function will return anint
. A warning may be given based on your flags.
– Rishikesh Raje
Nov 22 '18 at 4:05
add a comment |
Can main.c access f2() which is implemented and prototype declared inside test2.c
The function f2
will be taken as a default function which has return value of int and parameters int
if any. However, if you use different parameters, it will give an error.
From C99 onwards, the default function is not applicable and this will give an error.
Can main.c access f1()? or does it need to be declared as extern
Yes, it can access f1() as you have included test.h
However you also need to compile test.c
and give both files to the linker.
f1()
declaration in test.h
does not need to be declared as extern. By default, a function declaration is extern.
Does main.c have access to the x global variable inside test.c? Will it conflict with the global variable x (same name) defined in main.c?
You need to link the variables together. Once you do you will get a linker error for this.
To gain local scope is it mandatory to use static keyword?
If the variable is declared outside a function, it is global. To make it local scope you need to specifically use the static keyword.
Can static functions access global variables (static/non-static) defined in the same .c file ?
Yes
Can main.c access f2() which is implemented and prototype declared inside test2.c
The function f2
will be taken as a default function which has return value of int and parameters int
if any. However, if you use different parameters, it will give an error.
From C99 onwards, the default function is not applicable and this will give an error.
Can main.c access f1()? or does it need to be declared as extern
Yes, it can access f1() as you have included test.h
However you also need to compile test.c
and give both files to the linker.
f1()
declaration in test.h
does not need to be declared as extern. By default, a function declaration is extern.
Does main.c have access to the x global variable inside test.c? Will it conflict with the global variable x (same name) defined in main.c?
You need to link the variables together. Once you do you will get a linker error for this.
To gain local scope is it mandatory to use static keyword?
If the variable is declared outside a function, it is global. To make it local scope you need to specifically use the static keyword.
Can static functions access global variables (static/non-static) defined in the same .c file ?
Yes
edited Nov 21 '18 at 5:55
answered Nov 21 '18 at 5:50
Rishikesh RajeRishikesh Raje
5,6071826
5,6071826
In C90, the assumed return type of a function was indeedint
, but nothing was assumed about the arguments except that they were subject to default argument promotion rules. C99 and above does not, strictly, allow functions to be used before they are declared (or defined).
– Jonathan Leffler
Nov 21 '18 at 7:23
So, in practice anint
orint, int
orchar
argument is OK, but notfloat
– Rishikesh Raje
Nov 21 '18 at 7:29
Nope. Afloat
will be promoted todouble
, that's all. You can passchar *
andstruct Anything *
and so on too. Further, the compiler isn't required to check your calls for consistency. If you use an explicit function declaration likeextern int function();
then that has no prototype and any arguments are default promoted and there's no guarantee the compiler will cross-check different calls for consistency. The C99 rules require a declaration; they don't require a prototype declaration, though. You should tell your compiler to require strict prototype declarations if possible.
– Jonathan Leffler
Nov 21 '18 at 7:32
Hi, so I don't understand the first answer. what is a 'default function' ? My question is if main() can call f2(), even though it can't see the function declaration, as it's not in the test.h header file. will this return a compiler / linker / runtime error/warning ?
– Rosh
Nov 22 '18 at 1:48
@Rosh - In C89 and before, if there was no declaration the compiler would implicitly assume that the function will return anint
. A warning may be given based on your flags.
– Rishikesh Raje
Nov 22 '18 at 4:05
add a comment |
In C90, the assumed return type of a function was indeedint
, but nothing was assumed about the arguments except that they were subject to default argument promotion rules. C99 and above does not, strictly, allow functions to be used before they are declared (or defined).
– Jonathan Leffler
Nov 21 '18 at 7:23
So, in practice anint
orint, int
orchar
argument is OK, but notfloat
– Rishikesh Raje
Nov 21 '18 at 7:29
Nope. Afloat
will be promoted todouble
, that's all. You can passchar *
andstruct Anything *
and so on too. Further, the compiler isn't required to check your calls for consistency. If you use an explicit function declaration likeextern int function();
then that has no prototype and any arguments are default promoted and there's no guarantee the compiler will cross-check different calls for consistency. The C99 rules require a declaration; they don't require a prototype declaration, though. You should tell your compiler to require strict prototype declarations if possible.
– Jonathan Leffler
Nov 21 '18 at 7:32
Hi, so I don't understand the first answer. what is a 'default function' ? My question is if main() can call f2(), even though it can't see the function declaration, as it's not in the test.h header file. will this return a compiler / linker / runtime error/warning ?
– Rosh
Nov 22 '18 at 1:48
@Rosh - In C89 and before, if there was no declaration the compiler would implicitly assume that the function will return anint
. A warning may be given based on your flags.
– Rishikesh Raje
Nov 22 '18 at 4:05
In C90, the assumed return type of a function was indeed
int
, but nothing was assumed about the arguments except that they were subject to default argument promotion rules. C99 and above does not, strictly, allow functions to be used before they are declared (or defined).– Jonathan Leffler
Nov 21 '18 at 7:23
In C90, the assumed return type of a function was indeed
int
, but nothing was assumed about the arguments except that they were subject to default argument promotion rules. C99 and above does not, strictly, allow functions to be used before they are declared (or defined).– Jonathan Leffler
Nov 21 '18 at 7:23
So, in practice an
int
or int, int
or char
argument is OK, but not float
– Rishikesh Raje
Nov 21 '18 at 7:29
So, in practice an
int
or int, int
or char
argument is OK, but not float
– Rishikesh Raje
Nov 21 '18 at 7:29
Nope. A
float
will be promoted to double
, that's all. You can pass char *
and struct Anything *
and so on too. Further, the compiler isn't required to check your calls for consistency. If you use an explicit function declaration like extern int function();
then that has no prototype and any arguments are default promoted and there's no guarantee the compiler will cross-check different calls for consistency. The C99 rules require a declaration; they don't require a prototype declaration, though. You should tell your compiler to require strict prototype declarations if possible.– Jonathan Leffler
Nov 21 '18 at 7:32
Nope. A
float
will be promoted to double
, that's all. You can pass char *
and struct Anything *
and so on too. Further, the compiler isn't required to check your calls for consistency. If you use an explicit function declaration like extern int function();
then that has no prototype and any arguments are default promoted and there's no guarantee the compiler will cross-check different calls for consistency. The C99 rules require a declaration; they don't require a prototype declaration, though. You should tell your compiler to require strict prototype declarations if possible.– Jonathan Leffler
Nov 21 '18 at 7:32
Hi, so I don't understand the first answer. what is a 'default function' ? My question is if main() can call f2(), even though it can't see the function declaration, as it's not in the test.h header file. will this return a compiler / linker / runtime error/warning ?
– Rosh
Nov 22 '18 at 1:48
Hi, so I don't understand the first answer. what is a 'default function' ? My question is if main() can call f2(), even though it can't see the function declaration, as it's not in the test.h header file. will this return a compiler / linker / runtime error/warning ?
– Rosh
Nov 22 '18 at 1:48
@Rosh - In C89 and before, if there was no declaration the compiler would implicitly assume that the function will return an
int
. A warning may be given based on your flags.– Rishikesh Raje
Nov 22 '18 at 4:05
@Rosh - In C89 and before, if there was no declaration the compiler would implicitly assume that the function will return an
int
. A warning may be given based on your flags.– Rishikesh Raje
Nov 22 '18 at 4:05
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53405773%2fscope-of-function-prototypes-in-c-file-instead-of-header%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown