Pelles C forum
C language => Beginner questions => Topic started by: vedro-compota on December 20, 2011, 09:29:23 AM
-
Hi C athlets!)
Please tell me - where can be problem (except my head and hands :)))) in this situation -
If i move one custom function in additional C file from the main one - i get error =
: error #2048: Undeclared identifier 'TRUE'.
for line =
int result= TRUE;
both main and additional files have includes =
#include <stdio.h>
#include <stdlib.h>
if use this line in main.c - all will be ok,
big thanks in advance)
-
Post your code...
-
Do you have the same include files in both sources?
-
Do you have the same include files in both sources?
AlexN - yes - I have - without it compiler show much more errors.....
CommonTater , i've added project to this post - code is quite big
-
CommonTater , I'll publish only parts -the whole project you can see in attachments to the previous post
the entry file (with main() func) =
#include <stdio.h>
#include <stdlib.h>
#include "comlib.h"
#include "task1.h"
int main()
{ int result= TRUE;
os_founders_respect();
mainmenu();
return 0;
}
.............
the second source =
#include<stdio.h>
#include <stdlib.h>
#include "comlib.h"
#include "task1.h"
int task1standard(void)
{
//FILE *file1, *file2, *file3;
int result= TRUE;
char **arr,*ftext,**arr1,**arr2;
FILE *fp,*fp2,*rfp;
..................
}
additional comlib.c ( custom funcs for general purpose) =
#include <stdio.h>
#include <stdlib.h>
#include "comlib.h"
int tdarrs_cmp(char **arr1,char **arr2, FILE *rfp)
{ /* */
int k=0;
int n1=1;
int n2=1;
if (!rfp) rfp=fopen("compRESULT.txt","w");
printf("\n\n[%s]\n", "...comparation of two two-demision arrays showing is started...");
-
Privyet Mr. Vedro,
The C spec does not contain a boolean type and does not have definitions for TRUE or FALSE as such. The Windows API does, however, define these types.
This piece of code in task1code.c
#if defined(_WIN32) || defined (_WIN64)
#include <windows.h>
#define IN_WINDOWS 1
#endif
provides that file with the definition of TRUE.
If you want to use the symbol TRUE but you do not want to include windows.h then you should add the following to comlib.h which is included in each of your source files.
typedef int BOOL;
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
Udache Vam :D
-
privet i tebe , DMac ) but why it work in source file which contain the main() functions - because "Windows API does" ?
-
It works in your main file because you used #include <windows> in it... but nowhere else.
Each source file is a separate compilation unit... the compiler builds them file by file, creating obj files for each. If you want to include a header in all your files, you have to include it in all your files... either that or make a global header and include that in all your files... Either way the compiler only knows what you tell it... one file at a time.
-
i don't want to include headers in each file - but how be otherwise ? compiler shows many error of "undecleared" type -
for example - @ Undeclared identifier 'NULL' @
-
It's not about what YOU want to do... it's about what needs to be done to make it work.
I've never yet written a C source file that does not include at least a couple of headers.
Remember... when you are talking to C (through source code) you are giving instructions to a complete idiot. It will do exactly what you tell it, in the order you tell it... it won't care how wrong it is and it won't remember anything it's done. You have to tell it *everything* in little baby steps or it will not understand you.
-
Remember... when you are talking to C (through source code) you are giving instructions to a complete idiot. It will do exactly what you tell it, in the order you tell it... it won't care how wrong it is and it won't remember anything it's done. You have to tell it *everything* in little baby steps or it will not understand you.
CommonTater "I" know this!
Tell me - how to avoid the multiple including of equal headers ?!
all that you tell me - is right - but i don't understand this -
if compiler build each file separately - does it mean that we should include all needed headers in all source files??
-
[Tell me - how to avoid the multiple including of equal headers ?!
all that you tell me - is right - but i don't understand this -
if compiler build each file separately - does it mean that we should include all needed headers in all source files??
Yes, that's exactly what it means... and that is why we use include guards.
Remember that project tree I showed you... Here are some samples from the files in that project...
B_Main.c
// Main entry and gui code
#define WIN32_DEFAULT_LIBS
#define UNICODE
#define _UNICODE
// winapi
#include <windows.h>
#include <commctrl.h>
#include <shlwapi.h>
// private
#include <errorx.h>
#include <EZSplit.h>
// project
#include "B_Main.h"
#include "B_TreeView.h"
#include "B_ListView.h"
#include "B_Setup.h"
B_Setup.c
// Setup functions
// windows api
#define WIN32_DEFAULT_LIBS
#define UNICODE
#define _UNICODE
// windows
#include <windows.h>
#include <shlwapi.h>
// project
#include "B_Main.h"
B_Listview.c
// List View Functions
#define WIN32_DEFAULT_LIBS
#define UNICODE
#define _UNICODE
// winapi
#include <windows.h>
#include <commctrl.h>
#include <shlwapi.h>
// C-99
#include <wchar.h>
// project
#include "B_Main.h"
#include "B_LanEnum.h"
B_Treeview.c
// Tree View functions
#define WIN32_DEFAULT_LIBS
#define UNICODE
#define _UNICODE
// winapi
#include <windows.h>
#include <commctrl.h>
#include <shlwapi.h>
// private
#include <ErrorX.h>
// C-99
#include <wchar.h>
// project
#include "B_Main.h"
#include "B_ListView.h"
#include "B_LanEnum.h"
Getting the idea?
-
ok . as I see - it's possible to use #include in header itself =
#ifndef TASK1_H
#define TASK1_H
#include "comlib.h"
int task1standard(void);
int task1custom(void);
int testme(void);
#endif
is it a good practice ??
Getting the idea?
yeah - it's complex example - many includes in each source file....
-
ok . as I see - it's possible to use #include in header itself =
Yes it 's possible... but you should only do that if something in the header (constants, types, etc) need the included header.
for example... Here's a segment of one of the headers from that project...
#ifndef B_TREEVIEW_H
#define B_TREEVIEW_H
#include <windows.h>
#include <commctrl.h>
VOID tvRenameFavorite(HWND tvCtrl);
BOOL tvStartLabelEdit(HWND tvCtrl);
BOOL tvEndLabelEdit(LPNMTVDISPINFO NewItem);
BOOL tvExpandBranch(LPNMTREEVIEW Item);
BOOL tvCloseBranch(LPNMTREEVIEW Item);
I've included windows.h for the HWND typedef and commctrl.h because of typedefs needed by the function prototypes.... but only those needed by the header itself. If the header would work without the includes, I would not have them in there.
-
yeah - it's complex example - many includes in each source file....
That's the way it goes... each fle stands by itself, starting from nothing.
What you don't see, because of the way POIDE compiles from it's .ppj files is that the compiler is started for each new file and exits when done... everything is reset to zilch every time.
-
hm.....as i can judge by that fact that it's impossible to add heder file (.h) to Pelles C project ("add file to project" option ) - so it seems to be right to conclude that header is not build by compiler separately - so why it's not right to include (for example) common using <stdio.h> in all headers (with guards) - if this including is needed in all sources - but not in the header itself (as in your example)?
-
You don't have to --and can't-- add headers to the project... put them in your files.
The include files section of the tree is just a convenience for opening the files... POIDE parses them out of the source files for you.
It's done that way so that if you move the source to another compiler, your project will still build normally.
And... a compiler NEVER bulds header files... they're included into the source by the compiler as plain text when it reads the .c file.
-
It's done that way so that if you move the source to another compiler, your project will still build normally.
ok . purpose is clear )
one more moment -
if we use #ifdef guard - we'll get only one header including in each source file (compiler builds it separately) - but what about the final executed file - will it be free from the several same including ?
-
It's done that way so that if you move the source to another compiler, your project will still build normally.
ok . purpose is clear )
one more moment -
if we use #ifdef guard - we'll get only one header including in each source file (compiler builds it separately) - but what about the final executed file - will it be free from the several same including ?
First it's not #ifdef ... look closely... it's #ifndef ... if not defined.
Absolutely none of the text from source code makes it to the executable... The executable is pure machine code, so that's not an issue.
-
mechanism of compiler actions is not clear for me - if we in any vatiant won't have same parts of including in final .exe - why we need #ifndef (yes - "if not") guards ?
you help me so much - but to don't spend your time - i understand know that i need to read something about compiler and preprocessor actions - some article may be....
to have one including in one source - we simply should once write = #include something.h
so - guards is needed for the final - result file.....as I know think by my not so clever head without deep knowledge.....))
-
mechanism of compiler actions is not clear for me - if we in any vatiant won't have same parts of including in final .exe - why we need #ifndef (yes - "if not") guards ?
you help me so much - but to don't spend your time - i understand know that i need to read something about compiler and preprocessor actions - some article may be....
to have one including in one source - we simply should once write = #include something.h
so - guards is needed for the final - result file.....as I know think by my not so clever head without deep knowledge.....))
The compiler converts textual source code into machine code in objects... each object cones from one source page.
At this point there is no more source code. It's all machine language.
The linker then comes along and combines ojects to make the executable.
Absolutely none of the textual source code makes it into the executable.
You need the include guards so that a header file, included in another header file... per my example... is not read twice causing the compiler to think you're redefining stuff you've already defined.
The best way for you to "get it"... is to open a .obj and a .exe file in POIDE and have a look.
-
is not read twice
i'll continie your words - .....so if such header (as in your example - with #ifndef guard) was readed once in one file - it won't be readed during building of another one - or it won't be read more within the framework of each sourse file ? as i understand from your words - only second variant.
What is POIDE ? Google don't know in english - and i'm too))
-
POIDE is the editor you use with Pelles C...
No... include guards allow each header to be read once per source file.
Here's an example...
B_lanenum.h
// Local Area Network Enumerator
#ifndef B_NETENUM_H
#define B_NETENUM_H
#define UNICODE
#define _UNICODE
#include <windows.h>
And
B_listview.c
// List View Functions
#define WIN32_DEFAULT_LIBS
#define UNICODE
#define _UNICODE
// winapi
#include <windows.h>
#include <commctrl.h>
#include <shlwapi.h>
// C-99
#include <wchar.h>
// project
#include "B_Main.h"
#include "B_LanEnum.h"
Notice how both files include windows.h ... and the first file is included in the second one?
Without include guards windows.h would be read twice... But since it has include guards (go ahead, open it in the editor and look) it only gets processed once... preventing duplicate definition errors.
The separate source files you create and compile are just that... separate files. They are compiled individually and their content goes into individual .obj files (look in the output folder of your project). These files remain completely separate entities until the final linking stage merges them into an executable file.
-
These files remain completely separate entities until the final linking stage merges them into an executable file.
so finally - linker only combine all .obj into one .exe ? (without removing same functions from other .obj files )
-
These files remain completely separate entities until the final linking stage merges them into an executable file.
so finally - linker only combine all .obj into one .exe ? (without removing same functions from other .obj files )
Nope... the linker works on an object level... when you compile a source page, that creates 1 object. The entire object is then linked into the executable with the only change being to connect up the remaining function calls.
POLINK will not remove unused or duplicated code... that's your job, before compiling.
-
ok . as I see - it's possible to use #include in header itself =
#ifndef TASK1_H
#define TASK1_H
#include "comlib.h"
int task1standard(void);
int task1custom(void);
int testme(void);
#endif
Or if you only use Pelles C you can use:
#pragma once
Look in the help for more information. ;)
-
ok . as I see - it's possible to use #include in header itself =
#ifndef TASK1_H
#define TASK1_H
#include "comlib.h"
int task1standard(void);
int task1custom(void);
int testme(void);
#endif
Or if you only use Pelles C you can use:
#pragma once
Look in the help for more information. ;)
Excellent suggestion Alex...
You can also make it portable like this...
#ifdef __POCC__
#pragma once
#endif
With your usual include guards below right below it.