Author Topic: can't figure out difference between declaration and definition  (Read 18233 times)

0 Members and 3 Guests are viewing this topic.

Offline Kittu20Topic starter

  • Regular Contributor
  • *
  • Posts: 115
  • Country: in

I have been trying to understand how definition is different from declaration. I can't figure out difference between declaration and definition   

My code
Code: [Select]
#include<stdio.h>

void main()
{
 
   int x;          //  I have declared variable x

   int y = 10;     // I have declared variable y and assigning value  10 to y

}
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 11275
  • Country: fi
Re: can't figure out difference between declaration and definition
« Reply #1 on: January 05, 2023, 02:23:16 pm »
It's the same as the difference between a car, and a picture / registration sheet of a car.

Variable actually exists when it's put in memory somewhere. This is called definition.

You can tell the compiler that variable exists somewhere, and tell about its type, so compiler knows how to use it. This is called declaration.

In your example, both are definitions (x and y are actually created there), so no wonder you can't figure it out.

An example of declaration only:
Code: [Select]
extern int x;
« Last Edit: January 05, 2023, 02:25:49 pm by Siwastaja »
 
The following users thanked this post: Ian.M, DiTBho, Kittu20

Offline Kittu20Topic starter

  • Regular Contributor
  • *
  • Posts: 115
  • Country: in
Re: can't figure out difference between declaration and definition
« Reply #2 on: January 05, 2023, 03:38:52 pm »

Variable actually exists when it's put in memory somewhere. This is called definition.

You can tell the compiler that variable exists somewhere, and tell about its type, so compiler knows how to use it. This is called declaration.


I have define variable x in temp.c file and I am trying to access value of variable in hello.c

hello.c
Code: [Select]
#include<stdio.h>

int main ()
{
int x;
printf( "x = %d", x);
return 0;
}

temp.c
Code: [Select]
#include<stdio.h>

extern int x;

x = 10;

output
I get warning and wrong result
gcc -o hello hello.c temp.c
temp.c:5:1: warning: data definition has no type or storage class
 x = 10;
 ^
temp.c:5:1: warning: type defaults to 'int' in declaration of 'x' [-Wimplicit-int]

x = 4194432
 

Offline mfro

  • Regular Contributor
  • *
  • Posts: 226
  • Country: de
Re: can't figure out difference between declaration and definition
« Reply #3 on: January 05, 2023, 04:05:54 pm »
Your code has no (valuable) effect. It just prints the (uninitialized) value of a local variable x.

That is different from the global variable x (that the compiler is allowed to optimize away since its never accessed) that you defined in the other file.

That is even an errror since referencing a variable with no value yields UB.
« Last Edit: January 05, 2023, 04:08:56 pm by mfro »
Beethoven wrote his first symphony in C.
 

Offline Kittu20Topic starter

  • Regular Contributor
  • *
  • Posts: 115
  • Country: in
Re: can't figure out difference between declaration and definition
« Reply #4 on: January 05, 2023, 04:10:40 pm »
Your code has no (valuable) effect. It just prints the (uninitialized) value of a local variable x.

That is different from the global variable x (that the compiler is allowed to optimize away since its never accessed) that you defined in the other file.
making global variable is also give the same result

Code: [Select]
#include<stdio.h>
int x;

int main ()
{

printf( "x = %d", x);
return 0;
}

gcc -o hello hello.c temp.c
temp.c:5:1: warning: data definition has no type or storage class
 x = 10;
 ^
temp.c:5:1: warning: type defaults to 'int' in declaration of 'x' [-Wimplicit-int]
 

Offline mfro

  • Regular Contributor
  • *
  • Posts: 226
  • Country: de
Re: can't figure out difference between declaration and definition
« Reply #5 on: January 05, 2023, 04:13:54 pm »
Now you attempt to do an assignment in global scope (outside of any function body).

When would you expect that code to be executed?
« Last Edit: January 05, 2023, 04:16:11 pm by mfro »
Beethoven wrote his first symphony in C.
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 14131
Re: can't figure out difference between declaration and definition
« Reply #6 on: January 05, 2023, 04:17:59 pm »
Change the declaration in temp.c to a definition:
Code: [Select]
    int x=10;or even:
Code: [Select]
    extern int x=10;get rid of that illegal attempt at an assignment outside of any function, which the compiler is flagging: warning: data definition has no type or storage class
and add an extern declaration for it in main.c:
Code: [Select]
#include<stdio.h>

extern int x; // this one refers to the x defined in temp.c

int main ()
{
// int x; // don't declare X here - you don't want a local
printf( "x = %d", x);
return 0;
}
and it will 'just work'

It gets more complex when you want to create a header to declare all your variables - you probably should read: https://www.gamedev.net/tutorials/_/technical/general-programming/organizing-code-files-in-c-and-c-r1798/
Edit: AAGH! Gamedev.net have borked all their sourcecode formatting, by dropping the <pre> tags, which of course strips the newlines.   Unfortunately Archive.org don't seem to have a non-borked version.
« Last Edit: January 09, 2023, 10:24:45 am by Ian.M »
 

Offline Kittu20Topic starter

  • Regular Contributor
  • *
  • Posts: 115
  • Country: in
Re: can't figure out difference between declaration and definition
« Reply #7 on: January 05, 2023, 04:42:11 pm »
and it will 'just work'
Thank you It works

hello.c
Code: [Select]
#include<stdio.h>

extern int x;  // x defined in temp.c


int main ()
{
printf( "x = %d", x);
return 0;
}
x = 10

temp.c
Code: [Select]
#include<stdio.h>

int x = 10;  // x defined in temp.c
 

Offline Kittu20Topic starter

  • Regular Contributor
  • *
  • Posts: 115
  • Country: in
Re: can't figure out difference between declaration and definition
« Reply #8 on: January 05, 2023, 04:52:29 pm »
code to access function that is defined in temp.c file

hello.c
Code: [Select]
#include<stdio.h>

extern int foo();  // foo defined in temp.c


int main ()
{
int y = foo();
printf( "y = %d", y);
return 0;
}

temp.c
Code: [Select]
#include<stdio.h>

int foo()
{
int z = 1;
z++;
return z;
}

y = 2
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 14131
Re: can't figure out difference between declaration and definition
« Reply #9 on: January 05, 2023, 05:13:19 pm »
All function definitions in C are externally visible by default, and all function declarations are implicitly extern.   Unlike variables etc. you don't need to use the extern keyword for them.  The only type of function that isn't externally visible is one defined as static, which is limited to the scope of the single file where it is defined.

The rules in C++ are rather different and far more complex, but the vanilla 'C' subset of it is essentially the same.

N.B. use of extern in a declaration doesn't mean that the definition cant be in the same source file.   
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1803
  • Country: us
Re: can't figure out difference between declaration and definition
« Reply #10 on: January 05, 2023, 06:08:33 pm »
get rid of that illegal attempt at an assignment outside of any function, which the compiler is flagging: warning: data definition has no type or storage class
That is not illegal to have [what looks like] an assignment outside of a function [but is actually a definition-with-initializer].

That ends up being the actual definition of the storage for the variable (in the DS segment), which the linker will resolve all global variables defined without an initializer (tentative definitions) with at most one global variable definition with an initializer to be a single storage location, more simply said "they will be the same variable." (If multiple definitions exist with an initializer, it's a linker error, even if all of them are the same initial value.)

If all [whether one or more] definitions are tentative definitions (without a value specified), the variable will be created with a 0 value (in the BSS segment) and the linker will collapse the one or more of them to the same storage location.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 11275
  • Country: fi
Re: can't figure out difference between declaration and definition
« Reply #11 on: January 05, 2023, 06:21:07 pm »
C is indeed illogical - keyword extern is used to declare (and not define) a variable. But for a function, one can of course follow the same logic and declare
Code: [Select]
extern void function(int arg);
... but this extern keyword is optional, because the language knows it's only a declaration (not a definition) from the lack of function body ({ ... }) (there is semicolon instead).
 
The following users thanked this post: DiTBho

Offline golden_labels

  • Super Contributor
  • ***
  • Posts: 2509
  • Country: pl
Re: can't figure out difference between declaration and definition
« Reply #12 on: January 06, 2023, 02:41:38 am »
If you are declaring a variable inside a function, the question makes no sense. The distinction exists only if the item can be used in a place where it is not defined. I would suggest not thinking about that as some opposing concepts either. Those are not two ends of a single idea, but two separate concepts that are only related to each other.

First, you can define something. By that you are providing a concrete definition, a concrete instance. Using a car analogy someone mentioned earlier, you are building an actual car.

Now imagine you must tell about that car to someone, who has never seen it and the car is not anywhere around. That is the declaration. You are telling the compiler that there exists something with such and such features. So the compiler knows it exists, and you can refer to it. But it is not actually creating anything.

A situation like that arises commonly in two cases. First, if there are multiple compilation units and they must share some definitions. Only one compilation unit contains the definition. But others, which use it, must somehow know that definition exists and what it is. For those units you provide a declaration. For example if you have function doSomething in compilation unit fun.c, and you want main.c to use it, main.c must be told such a thing exists:
Code: [Select]
// fun.c
#include <stdio.h>

// Definition of `doSomething`
void doSomething(int x) {
    printf("Do something: %d\n", x);
}
Code: [Select]
// main.c

void doSomething(int); // Declaration of `doSomething`

int main(void) {
    doSomething(12);
    return 0;
}
The declaration tells compiler, while it compiles “main.c”, that there is some function called doSomething, which accepts a single int argument and returns nothing. It doesn’t tell what it does, how it is implemented or where to find it. It just provides minimum information required for the later invocation to be syntactically valid.

Similarly, for variables:
Code: [Select]
// var.c
int x = 12; // Definition of `x`
Code: [Select]
// main.c
#include <stdio.h>

extern int x; // Declaration of `x`

int main(void) {
    printf("x = %d\n", x);
    return 0;
}

Another case is a single compilation unit, where e.g. functions are referencing each other. Obviously the earlier one will not know about the latter one. For this reason the latter one must be declared earlier, so it is known to the compiler.

The situation with extern and static is a bit complicated, because of C’s history. Basically it’s a mix of shorthand notation, where linkage is implied, and assumptions from decades ago. It’s not illogical: it’s just permitting things to be not explicitly stated, with the defaults being defined by ancient conventions.
Why 📎 | We live in times when half of people have IQ below 100.
 

Offline Kittu20Topic starter

  • Regular Contributor
  • *
  • Posts: 115
  • Country: in
Re: can't figure out difference between declaration and definition
« Reply #13 on: January 06, 2023, 11:46:40 am »

Have I used header file correctly ?

hello.c

Code: [Select]
#include<stdio.h>
#include"temp.h"

int main ()
{
printf( "x = %d", x);
return 0;
}

temp.h
Code: [Select]
extern int x;
temp.c
Code: [Select]
#include<stdio.h>
int x = 5;

output
x = 5
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1803
  • Country: us
Re: can't figure out difference between declaration and definition
« Reply #14 on: January 06, 2023, 12:26:20 pm »
Yes, though it’s typical practice to also include temp.h from temp.c as well. (Not needed for this toy example, but extremely common in actual code.)
 

Offline IDEngineer

  • Super Contributor
  • ***
  • Posts: 1981
  • Country: us
Re: can't figure out difference between declaration and definition
« Reply #15 on: January 06, 2023, 01:28:49 pm »
Probably just me, but I've always felt that C uses the keywords "definition" and "declaration" backwards. Every time I read one, it automatically feels like the intent of the other. To "define" something doesn't necessarily create it, but "declaring a variable" sure sounds like you're calling it into existence. At least to me.
 

Offline Kittu20Topic starter

  • Regular Contributor
  • *
  • Posts: 115
  • Country: in
Re: can't figure out difference between declaration and definition
« Reply #16 on: January 06, 2023, 01:50:25 pm »

I have compiled following program and it gives output.
hello.c
Code: [Select]
#include<stdio.h>
#include"temp.h"
 
int main (void)
{
    printf("%d\n", get_number());
 
    return 0;
}


temp.c
Code: [Select]
#include "temp.h"
 
int get_number(void)
{    int x = 5;
    return x;
}

 I understand both hello.c and temp.c file but I  don't understand  what's happens in temp.h file 

temp.h
Code: [Select]
#ifndef _OTHER_H_
#define _OTHER_H_
 
int get_number(void);
 
#endif
 
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1803
  • Country: us
Re: can't figure out difference between declaration and definition
« Reply #17 on: January 06, 2023, 02:12:30 pm »
I understand both hello.c and temp.c file but I  don't understand  what's happens in temp.h file 

temp.h
Code: [Select]
#ifndef _OTHER_H_
#define _OTHER_H_
 
int get_number(void);
 
#endif
 
Think of that expression as saying, "Hey compiler, there is or will be a function <somewhere> that takes no parameters '(void)', returns an integer 'int', and is called 'get_number'. So, when you see someone calling a function get_number, ensure that they pass it no parameters."

Then, in a later stage, after all the files have been individually compiled and are ready to be assembled together into a single program by the linker, the linker has to find the function get_number(void) somewhere, but that's at a later stage.

One thing to put into your mental model is that all of the .c files are compiled individually* and the compiler can only "see" and "use" information that is in those .c files (after the pre-processor runs, which is what includes the text of the included .h files). So, it has to know the declaration of the get_number function in order to compile the call to it in main in hello.c.

Minor tip: I would change _OTHER_H_ to _TEMP_H_.

* This is a slight hand-wave, but it's sufficient for this thread.
« Last Edit: January 06, 2023, 02:14:08 pm by sokoloff »
 

Offline mfro

  • Regular Contributor
  • *
  • Posts: 226
  • Country: de
Re: can't figure out difference between declaration and definition
« Reply #18 on: January 06, 2023, 04:41:11 pm »
Probably just me, but I've always felt that C uses the keywords "definition" and "declaration" backwards. Every time I read one, it automatically feels like the intent of the other. To "define" something doesn't necessarily create it, but "declaring a variable" sure sounds like you're calling it into existence. At least to me.

In C, keywords are more often than not doing something else than what their names imply. Static isn't static most of the time, const isn't const (it can even be volatile), there's nothing automated with auto, restricted pointers aren't restricted at all (but even more free than all others) and if register lives in a register is solely the compiler's choice (not yours).

You just need to live with that.
Beethoven wrote his first symphony in C.
 

Offline mfro

  • Regular Contributor
  • *
  • Posts: 226
  • Country: de
Re: can't figure out difference between declaration and definition
« Reply #19 on: January 09, 2023, 09:07:47 am »
Minor tip: I would change _OTHER_H_ to _TEMP_H_.

wouldn't recommend leading underscores at all as they are reserved to the compiler and standard library implementation.
Beethoven wrote his first symphony in C.
 
The following users thanked this post: newbrain, sokoloff

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 5098
  • Country: gb
Re: can't figure out difference between declaration and definition
« Reply #20 on: January 09, 2023, 10:17:34 am »
In C, keywords are more often than not doing something else than what their names imply. Static isn't static most of the time, const isn't const (it can even be volatile), there's nothing automated with auto, restricted pointers aren't restricted at all (but even more free than all others) and if register lives in a register is solely the compiler's choice (not yours).

You just need to live with that.

LOL, but that's sadly so true
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1803
  • Country: us
Re: can't figure out difference between declaration and definition
« Reply #21 on: January 11, 2023, 02:08:38 pm »
Minor tip: I would change _OTHER_H_ to _TEMP_H_.
wouldn't recommend leading underscores at all as they are reserved to the compiler and standard library implementation.
TIL something about the C standard. Thanks!
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 11275
  • Country: fi
Re: can't figure out difference between declaration and definition
« Reply #22 on: January 12, 2023, 07:00:40 am »
And just use
#pragma once
at the beginning of the header file.

Every compiler has supported it for at least 2-300 years. Write less boilerplate, make fewer typos.
 

Offline sokoloff

  • Super Contributor
  • ***
  • Posts: 1803
  • Country: us
Re: can't figure out difference between declaration and definition
« Reply #23 on: January 12, 2023, 11:16:52 am »
#pragma once is not part of the language standard. Whether that matters to you depends on the project circumstances.
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 9204
  • Country: de
  • A qualified hobbyist ;)
Re: can't figure out difference between declaration and definition
« Reply #24 on: January 12, 2023, 12:07:22 pm »
C is indeed illogical - keyword extern is used to declare (and not define) a variable. But for a function, one can of course follow the same logic and declare
Code: [Select]
extern void function(int arg);
... but this extern keyword is optional, because the language knows it's only a declaration (not a definition) from the lack of function body ({ ... }) (there is semicolon instead).

There's something called 'forward declaration' (also 'function prototype', required by C99), i.e.:
Code: [Select]
void Function2(void);

void Function1(void)
{
  ...
  Function2();
  ...
}

void Function2(void)
{
  ...
}

An "extern void Function2(void);" would tell the compiler/linker that Function2() is in another file.
Edit: Since most compilers take any function declaration with an implicit 'extern' the statement above can be ignored. Because this contradicts the explicit use of 'extern' for variables some software developers consider it a flaw.
« Last Edit: January 12, 2023, 05:57:27 pm by madires »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

-->