Pelles C forum

C language => Beginner questions => Topic started by: vedro-compota on December 20, 2011, 09:29:23 AM

Title: error - Undeclared identifier 'TRUE' after moving
Post 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  =
Quote
: error #2048: Undeclared identifier 'TRUE'.

for line  =
Code: [Select]
   int result= TRUE;

both main and additional  files  have includes =

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

if use this line in main.c  - all will be ok,

big thanks in advance)

Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 20, 2011, 10:15:15 AM
Post your code...
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: AlexN on December 20, 2011, 10:52:50 AM
Do you have the same include files in both sources?
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: vedro-compota on December 20, 2011, 02:54:01 PM
Quote
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
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: vedro-compota on December 20, 2011, 03:18:17 PM
CommonTater , I'll publish only parts -the whole project you can see in attachments to the previous post

the entry file (with main() func)  =
Code: [Select]
#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 =

Code: [Select]
#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) =
 
Code: [Select]
#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...");
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: DMac on December 20, 2011, 04:58:30 PM
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
Code: [Select]
#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.
Code: [Select]
typedef int BOOL;

#ifndef FALSE
#define FALSE  0
#endif

#ifndef TRUE
#define TRUE  1
#endif

Udache Vam :D
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: vedro-compota on December 20, 2011, 07:40:25 PM
 privet  i tebe , DMac ) but why it work in source file which contain the main() functions - because  "Windows API does" ?
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 20, 2011, 07:59:04 PM
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.


Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: vedro-compota on December 20, 2011, 08:19:10 PM
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' @
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 20, 2011, 08:34:48 PM
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.




Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: vedro-compota on December 20, 2011, 08:44:18 PM
Quote
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??
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 20, 2011, 08:46:27 PM
[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
Code: [Select]
// 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
Code: [Select]
// 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
Code: [Select]
// 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
Code: [Select]
// 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?

 
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: vedro-compota on December 20, 2011, 08:53:05 PM
ok . as I see - it's possible to use #include in header itself =
Code: [Select]
#ifndef  TASK1_H
#define  TASK1_H

#include "comlib.h"
int task1standard(void);
int task1custom(void);
int testme(void);

#endif

 is it a good practice ??

Quote
Getting the idea?
yeah - it's complex example - many includes in each source file....
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 20, 2011, 09:01:37 PM
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...
Code: [Select]
#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.
 


 
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 20, 2011, 09:03:46 PM
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.

 
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: vedro-compota on December 20, 2011, 09:16:15 PM
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)?
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 20, 2011, 09:38:34 PM
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.
 
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: vedro-compota on December 20, 2011, 10:04:33 PM
Quote
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 ?
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 20, 2011, 10:14:12 PM
Quote
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.
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: vedro-compota on December 20, 2011, 10:29:32 PM
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   =
Code: [Select]
#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.....))
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 20, 2011, 11:26:20 PM
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   =
Code: [Select]
#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.
 

 
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: vedro-compota on December 20, 2011, 11:50:07 PM
Quote
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))
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 21, 2011, 01:46:23 AM
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
Code: [Select]
// Local Area Network Enumerator
#ifndef B_NETENUM_H
#define B_NETENUM_H
#define UNICODE
#define _UNICODE
#include <windows.h>

And
B_listview.c
Code: [Select]
// 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.
 
 
 




 
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: vedro-compota on December 21, 2011, 03:14:47 PM
Quote
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 )
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 21, 2011, 08:21:51 PM
Quote
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.
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: AlexN on December 23, 2011, 09:18:17 AM
ok . as I see - it's possible to use #include in header itself =
Code: [Select]
#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:
Code: [Select]
#pragma onceLook in the help for more information. ;)
Title: Re: error - Undeclared identifier 'TRUE' after moving
Post by: CommonTater on December 23, 2011, 09:27:25 AM
ok . as I see - it's possible to use #include in header itself =
Code: [Select]
#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:
Code: [Select]
#pragma onceLook in the help for more information. ;)

Excellent suggestion Alex...

You can also make it portable like this...
Code: [Select]
#ifdef __POCC__
#pragma once
#endif
With your usual include guards below right below it.