Author: Dann Corbit
Date: 18:44:35 06/11/04
Go up one level in this thread
On June 11, 2004 at 21:34:55, Dann Corbit wrote:
>On June 11, 2004 at 20:43:40, Uri Blass wrote:
>
>>On June 11, 2004 at 19:08:21, Dann Corbit wrote:
>>
>>>On June 11, 2004 at 15:36:29, Uri Blass wrote:
>>>
>>>>On June 11, 2004 at 14:03:14, Dann Corbit wrote:
>>>>
>>>>>On June 11, 2004 at 13:28:54, Uri Blass wrote:
>>>>>
>>>>>>On June 11, 2004 at 13:03:43, Dann Corbit wrote:
>>>>>>
>>>>>>>On June 11, 2004 at 09:42:25, Uri Blass wrote:
>>>>>>>
>>>>>>>>On June 11, 2004 at 09:04:28, Rémi Coulom wrote:
>>>>>>>>
>>>>>>>>>On June 11, 2004 at 08:30:29, Uri Blass wrote:
>>>>>>>>>
>>>>>>>>>>I have a version of movei that is movei00_8_236.exe
>>>>>>>>>>
>>>>>>>>>>It is using a lot of files when the number 236 is in it.
>>>>>>>>>>
>>>>>>>>>>When I change to movei00_8_237.exe I want the new version to use files with the
>>>>>>>>>>number 237 in it(the reason is that otherwise if I put both 236.exe and 237.exe
>>>>>>>>>>in the same folder they use the same files and can change the same book files
>>>>>>>>>>and I do not want 237 to learn to change it's book from games of 236).
>>>>>>>>>>
>>>>>>>>>>Of course it is possible to put 236 and 237 in different folders but I do not
>>>>>>>>>>like this solution.
>>>>>>>>>>
>>>>>>>>>>I think that the best solution is to tell the program to read the name of the
>>>>>>>>>>exe file and copy it to a string and use it when it decide about the names of
>>>>>>>>>>the files that it reads or create.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>The question is how to do it.
>>>>>>>>>>
>>>>>>>>>>Uri
>>>>>>>>>
>>>>>>>>>if your main function is
>>>>>>>>>
>>>>>>>>>int main(int argc, char *argv[])
>>>>>>>>>
>>>>>>>>>then argv[0] is the name of the exe
>>>>>>>>>
>>>>>>>>>Rémi
>>>>>>>>
>>>>>>>>Thanks
>>>>>>>>
>>>>>>>>It is
>>>>>>>>__cdecl main(void)
>>>>>>>>
>>>>>>>>I do not remember why I need the cdecl and it was a long time ago but if I
>>>>>>>>remember correctly I needed it when I tried to change the .c files to .cpp
>>>>>>>>files(I do not use C++ code but only C but I find it easier to do things with
>>>>>>>>cpp code(for example I know from experience that checking bounds does not work
>>>>>>>>correctly with files that end with .c).
>>>>>>>
>>>>>>>Some compilers do some rudimentary bounds checking. However, the reliable way
>>>>>>>to do it is to use a bounds checker. There are lots of them.
>>>>>>
>>>>>>I have bound checkers
>>>>>>
>>>>>>I found that it did not work correctly with C files and the reply that I got
>>>>>>from compuware that it is a limitation of the C language.
>>>>>>
>>>>>>Here is a simple program that I generated to demonstrate the problem:
>>>>>>
>>>>>>
>>>>>>#include "stdio.h"
>>>>>>
>>>>>>
>>>>>>
>>>>>>typedef struct
>>>>>>{
>>>>>> int m;
>>>>>> int n;
>>>>>>
>>>>>>}
>>>>>>hist_t;
>>>>>>
>>>>>>hist_t PADDED_hist_dat[1000];
>>>>>>hist_t * const hist_dat=PADDED_hist_dat+1;
>>>>>>
>>>>>>void main(void)
>>>>>>{
>>>>>> int sq;
>>>>>> for (sq=998;sq<=1000;sq++)
>>>>>> printf(" %d ", hist_dat[sq].n);
>>>>>>}
>>>>>>
>>>>>>
>>>>>>boundchecker finds a mistake only when sq=1000
>>>>>
>>>>>It is understandably difficult to track a pointer when due to alignment or the
>>>>>presence of other data, the element addressed may actually live in your data
>>>>>space.
>>>>>
>>>>>>Note that if I replace
>>>>>> printf(" %d ", hist_dat[sq].n);
>>>>>>by
>>>>>> printf(" %d ", hist_dat[sq].m);
>>>>>>
>>>>>>boundcheker reports an error in the right time when sq=999
>>>>>
>>>>>This is not a function of C or C++ language. There is no logical reason why
>>>>>they can find the error with C++ but not with C.
>>>>>
>>>>>>The reply that I got from compuware was that it is not a bug in checkerbound but
>>>>>>limitation of the C language:
>>>>>>
>>>>>>" IF this code is compiled as a .cpp, we know from the
>>>>>>symbol table that the struct hist_t is actually an 8 byte object, but under
>>>>>>C, the symbol table only contains the size of the member, so we fail to
>>>>>>report the overrun at the correct point for the member variable m since we
>>>>>>are only looking ahead 4 bytes rather than the full 8."
>>>>>
>>>>>They should be able to instrument the code to detect the error.
>>>>>
>>>>>In this tiny program, there are other errors, some of which you may not expect.
>>>>>
>>>>>Are you aware that the main() function should *not* be declared as returning
>>>>>void?
>>>>
>>>>dependent on your definition of error.
>>>>
>>>>If the application runs there are no errors that the computer see(otherwise the
>>>>program cannot run)
>>>>
>>>>If you want to convince me that it is an error then you need to explain what
>>>>problems can be because of that definition.
>>>
>>>It can crash the computer, do nothing out of the ordinary, or cause Scott Nudds
>>>to come flying out of your nose. Using "void main()" is an example of undefined
>>>behavior.
>>>
>>>If you think I am being mellodramatic, I once sent a program to calculate pi to
>>>a fellow in England. It crashed his computer system. We traced the problem to
>>>"void main(void)".
>>>
>>>For some compilers, void main() is allowed as an undocomented extension.
>>>However, the next iteration of the compiler may cause it to crash, to format
>>>your hard disk, or to cause your computer to hop about the room while whistling
>>>the star spangled banner.
>>>
>>>From the C FAQ:
>>>
>>>1.25b: What's the right declaration for main()?
>>> Is void main() correct?
>>>
>>>A: See questions 11.12a to 11.15. (But no, it's not correct.)
>>>
>>>
>>>11.12a: What's the correct declaration of main()?
>>>
>>>A: Either int main(), int main(void), or int main(int argc,
>>> char *argv[]) (with alternate spellings of argc and *argv[]
>>> obviously allowed). See also questions 11.12b to 11.15 below.
>>
>>Thanks but this seems to be not correct for my main.cpp file(I explained the
>>reason that I change from c to cpp).
C++ has the same semantics for main() as C does.
From the ANSI/ISO C++ language specification: ISO/IEC 14882:1998(E):
3.6.1 Main function
1 A program shall contain a global function called main, which is the designated
start of the program. It is implementation defined whether a program in a
freestanding environment is required to define a main function. [Note: in a
freestanding environment, startup and termination is implementation defined;
startup contains the execution of constructors for objects of namespace scope
with static storage duration; termination contains the execution of destructors
for objects with static storage duration.]
2 An implementation shall not predefine the main function. This function shall
not be overloaded. It shall have a return type of type int, but otherwise its
type is implementation defined.
All implementations shall allow both of the following definitions of main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
In the latter form argc shall be the number of arguments passed to the program
from the environment in which the program is run. If argc is nonzero these
arguments shall be supplied in argv[0] through argv[argc1] as pointers to the
initial characters of null terminated multibyte strings (NTMBSs) (17.3.2.1.3.2)
and argv[0] shall be the pointer to the initial character of a NTMBS that
represents the name used to invoke the program or "". The value of argc shall be
nonnegative. The value of argv[argc] shall be 0. [Note: it is recommended that
any further (optional) parameters be added after argv.]
3 The function main shall not be used (3.2) within a program. The linkage (3.5)
of main is implementation defined.
A program that declares main to be inline or static is ill formed. The name main
is not otherwise reserved. [Example: member functions, classes, and enumerations
can be called main, as can entities in other namespaces. ]
4 Calling the function
void exit(int);
declared in <cstdlib> (18.3) terminates the program without leaving the current
block and hence without destroying any objects with automatic storage duration
(12.4). If exit is called to end a program during the destruction of an object
with static storage duration, the program has undefined behavior.
5 A return statement in main has the effect of leaving the main function
(destroying any objects with automatic storage duration) and calling exit with
the return value as the argument. If control reaches the end of main without
encountering a return statement, the effect is that of executing return 0;
>>I have now
>>int __cdecl main(int argc, char *argv[])
>>
>>I had cdecl without int but I added int after reading your post
__cdecl is a Microsoft extension. You need to use this declaration if you are
using a Microsoft extension to compile functions as some calling convention
other than the C calling convention (e.g fastcall or stdcall).
If you do this, your program will not be portable to other compilers besides
Microsoft C/C++.
To get around that, you can do this:
#ifdef _MSC_VER
#define CDECL __cdecl
#else
#define CDECL
#endif
int CDECL main(void)
{
/* do stuff */
return 0;
}
>>I get warning from the compiler if I try to change to
>>int main(int argc, char *argv[])
>>
>>warning C4007: 'main' : must be '__cdecl'
>>
>>It means that there is at least one another possibility to declare main(at least
>>in C++).
When you decorate the name of main with a non-portable calling convnetion, you
have exceeded the bonds of C++ and are now venturing into implementation defined
behavior.
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.