|
It's not a recommended practice to use global variables. What is it that you are trying to do? We can hopefully make some alternative suggestions.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
Agreed! but my application is such that renaming my application executable to some other name than the original makes it works differently. so i need a global flag which indiactes the state of the app (based on the name) thru out the application classes. so for this purpose...i cud onmly think of application wide variables.
can u suggest any other way to accomplish this.
Thanx & Regards
rIsHaBh
|
|
|
|
|
It's generally not a good idea to use global variables.
If you must use them, declare them (with extern) in a header file. Include the header file in any .cpp file where you want the global variables to be used.
Put the definition of the global variable (no extern) in one (and only one) of your .cpp files.
|
|
|
|
|
And if you must do it, put them in a namespace!
namespace Global
{
extern bool m_Execute;
};
|
|
|
|
|
Nah, just name them with the g_ prefix. Namespaces can always be bypassed with the using directive. The g_ prefix is clear and simple.
Regards,
Alvaro
Hey! It compiles! Ship it.
|
|
|
|
|
And can also potentially clash with other globals. It doesn't cost anything to use a namespace and you gain that bit of extra clarity (even though you can work round it) - besides, you can still name them g_ anyway!
|
|
|
|
|
Namespaces can also clash, especially if everyone decides to use Global as the one for global variables.
This goes back to the argument of how to use global variables. I never use them when writing library code. In other words, if I'm writing a DLL that exports code to be used by multiple DLLs/EXEs, I stay away from symbols/names that can potentially clash with other symbols/names in other libraries.
However, I've found global variables extremely convenient for several EXEs where there was only one database connection, one INI file, one set of input parameters, one log file, etc. I just named my variables g_db, g_ini, g_input, and g_log and used those all over the app. It made the code a lot easier to write (vs. Global.m_db all over the place), a lot easier to read (the g_ tells you it's global), and with no chance of name collisions (since only my program had these).
So my point is, everything has a use. You just need to know the when and the how, and even things such as global variables can help us write better code.
Regards,
Alvaro
Hey! It compiles! Ship it.
|
|
|
|
|
I wonder who's the nutcase that rated your post a 1.
You gave the proper answer, and you get my 5.
Regards,
Alvaro
Hey! It compiles! Ship it.
|
|
|
|
|
what is the difference between variable definiation and declaration
rIsHaBh
|
|
|
|
|
When you declare something you tell the compiler that a symbol of that name and type will be available at link time.
When you define something, you tell the compiler not only that the variable or function exists, but that it must reserve space for that variable, or create object code for that function, in the current translation unit (.cpp file). When you declare a function or method, you don't include the function body.
You generally put your declarations in header files, which can be shared by many .cpp files that might be part of your program.
You put your definitions in a .cpp file. Generally, each .cpp file together with all the headers it includes make a single translation unit that the compiler converts to a single object file. The object file contains object code for functions defined within the translation unit, and reserves space for static or global variables defined within the translation unit, but it contains only references to functions or variables that were declared but not defined. The linker resolves the references to declared symbols to when it links the object files together with any required libraries to make your final executable.
So in compiling all the parts of your program, the compiler will see the declaration of a symbol several times (once per translation unit that sees the symbol declared) but the definition only once (in the translation unit where the symbol is defined).
|
|
|
|
|
|
Since this is MFC - you don't really need global variables. That is because the MFC framework gives you one automatically - your application class. Just put anything of global scope in your application class (usually CYourProgramApp) and make appropriate accessor functions for it.
You can always get the app by calling AfxGetApp .
Or, as others have said, you can design your code so that it doesn't use globals...
If your nose runs and your feet smell, then you're built upside down.
|
|
|
|
|
Hi All,
I would like to know how the File Handling APIs provided by Windows are passed on to the NTFS driver. What are the various layers through which these API calls are taken before the file system driver actually converts it into low level system calls. Suppose I want to programmatically open a file in C++, then I would make a call to OpenFile() method provided by Win SDK. Then, what are the various stages before the call is actually taken by the file system driver. Do we have any control at the driver stage of the call?
Please help,
Abhishek.
Learning is a never ending process of Life.
|
|
|
|
|
first lection for
abhinarulkar wrote:
Learning is a never ending process of Life.
... you call CreateFile and NOT OpenFile!
the call is passed via interrupt 2e to the kernel, then to the io manager, cache manager, file system, storage class driver, something like that
Don't try it, just do it!
|
|
|
|
|
Hi,
I meet an exception "Float Invalid Opration" and to debug, jump into "Disassembly Window" and "Call Stack Window" in "ntdll.dll". I do not know which function throw the exception, how can I know it?
Which reasons cause the "Float Invalid Opration", in general? How can I get
rid of it?
Thanks a lot!
|
|
|
|
|
Run the program in Debug mode( press F5 ), and when an exception is raised, just right click anywhere on the toolbar( without stopping the program ), and select the 'CallStack' option from the menu. Now you will be able to see the stack for the program.
"A robust program is resistant to errors -- it either works correctly, or it does not work at all; whereas a fault tolerant program must actually recover from errors."
|
|
|
|
|
Hello, Sir:
I have a matter with the floating point arithmetics test. And I have some function that was write assembler language. But I want to realization it on VC++. I don't how to do. And I have tried, but i can't success, Because i don't what those assembler is means. Can you help me?
The Source Code :
CARRY_ERROR EQU 1
REG_BITS_ERROR EQU 2
FLAGS_ERROR EQU 3
BCD_ERROR EQU 4
MUL_DIV_ERROR EQU 5
JMP_ERROR EQU 6
MUL386_ERROR EQU 7
LOGIC1_ERROR EQU 8
LOGIC2_ERROR EQU 9
CMPS_ERROR EQU 10
IOS_ERROR EQU 11
STRS_ERROR EQU 12
MOVS_ERROR EQU 13
PUSHA_ERROR EQU 14
NUM_REG = 8 ; NUMBER OF REGISTERS IN THE NPX
NUM_BITS = 64 ; # of bits to test in the significant
NUM_EXP = 14 ; # of bits to test in the exponent
;*****************************************************************************
;_ChkFpuArith
; Test FPU Arithmetics
; Entry: None
; Exit: AX=1 if PASS , AX=0 if Fail
;*****************************************************************************
PUBLIC _ChkFpuArith
_ChkFpuArith PROC far
push ds
push es
push bx
push si
push di
mov ax,CPUGROUP
mov ds,ax
finit ; initialize the npx
cli ; disable intrerrupts. then load the
mov control_word,133fh ; ctrl word: no exceptions, no interrupts
fldcw control_word ; 64 bits, round even, infinity affine
mov reg_counter,num_reg ; for each register do:
t001:
fild ds:two ; initialize register
mov bit_counter,num_bits ; for each bit in the significand field:
t002:
call check_significand ; if carry bit not set, flag error
jc short t004 ; and return
fimul ds:two ; generate carry (register*2)
fisub ds:one ; move bit to the right (register-1)
dec bit_counter
jnz short t002 ; end for
fstp st(0) ; initialize register (store and pop)
fild ds:four ; integer load 4
mov bit_counter,num_exp ; for each bit in the exponent field do:
t003:
call check_exponent ; if exponent incorrect, return
jc short t004 ;
fmul st,st(0) ; squares the content of the stack top
fidiv ds:two ; divide by two, sets next bit in exponent
dec bit_counter
jnz short t003 ; end for
xor ax,ax ; zero expected condition bits.
call condition_bits ; if register <> positive & nonzero
t004:
jnz short t007 ; flag error and return
fchs ; generate a nan (sqrt(-number))
fsqrt
mov ah,045h ; set expected condition bits.
call condition_bits ; if register <> (nan or infinity)
jnz short t007 ; flag error and return
fstp st(0) ; store and pop. initialize register 0
fldz ; load +0.0 into stack 0
mov ah,040h ; set expected condition bits.
call condition_bits ; if register <> zero (+ or -)
jnz short t007 ; flag error and return
fsub ds:alarge ; make register negitive and nonzero
mov ah,001h ; set expected condition bits.
call condition_bits ; if register <> negitive and nonzero
jnz short t007 ; flag error and return
dec reg_counter ; endif
jz short t006 ;
jmp t001
t006:
call check_stack ; check each register for -large
jz short t008
t007:
mov ax,0
jmp @F
t008:
mov ax,1
@@:
sti
pop di
pop si
pop bx
pop es
pop ds
retf
_ChkFpuArith ENDP
condition_bits PROC near
ftst ; test stack top against 0.0, set condition bits
fstsw status_word ; store the status word
fwait ; wait for npx to finish
and status_word,4700h ; strip off all but the condition bits
cmp status_word,ax
ret
condition_bits ENDP
;
; check_significand
;
check_significand PROC near
mov ax,ds
mov es,ax
fsave full_npx_state ; put the npx reg stack in memory
frstor full_npx_state ; don't let npx re-initialize
fwait
xor al,al ; clear out the temporary buffer
mov di,offset temp_buff
mov cx,8
rep stos es:temp_buff
mov temp_buff+7,80h ; set bit 63
xor ah,ah ; calculate position of other bit
mov al,bit_counter ; divide by the # of bits in a byte
dec ax
mov bl,8
div bl ; divide by the # of bits in a byte
mov bx,ax
xor ah,ah
mov si,ax ; add byte offset of significand byte
mov al,bh ; translate the bit # to an actual
mov bx,offset ds:bit_table ; bit position
xlat ds:bit_table
or byte ptr temp_buff[si],al ; set bit in the temp_buff
mov si,offset temp_buff
mov di,offset byte ptr full_npx_state+14
mov cx,8
repe cmps temp_buff,byte ptr es:full_npx_state ; compare the two
jz short chk_sig_ok
stc ; Set carry flag is 1
jmp @F
chk_sig_ok:
clc ; Set carry flag is 0
@@:
ret
check_significand ENDP
;
; check_exponent
;
check_exponent PROC near
fsave full_npx_state ; put the npx reg stack in memory
frstor full_npx_state ; don't let npx re-initialize
fwait
mov si,22 ; save the exponent offset in the
mov al,num_exp ; index register. then calculate the
sub al,bit_counter ; corresponding bit position
mov bx,offset ds:bit_table ; load the address of the offset table
cmp al,8 ; if in next byte, then do:
jl short chk_ex_1
sub al,8
xlat ds:bit_table
mov ah,al
xor al,al
jmp short chk_ex_2
chk_ex_1:
xlat ds:bit_table
xor ah,ah
chk_ex_2:
or ax,04000h ; set non-fraction bit
fwait ; wait for npx to catch up
cmp full_npx_state[si],ax ; if exponent not equal, then
jz short chk_ex_3
stc
ret
chk_ex_3:
clc
ret
check_exponent ENDP
;
; check_stack
;
check_stack PROC near
mov ax,ds
mov es,ax
fsave full_npx_state ; get the register stack into the buffer
fwait
mov ax,8 ; eight registers to check
mov di,offset bptr full_npx_state+14
chk_stk_01:
mov si,offset ds:minus_large
mov cx,10 ; load a loop count for 10 bytes
rep cmps ds:minus_large,byte ptr es:full_npx_state
jnz short chk_stk_02
dec ax
jnz short chk_stk_01
chk_stk_02:
ret
check_stack ENDP
|
|
|
|
|
Hello,
I have an SDI application in wich I need several different views of the data. These views are not shown together (not a splitter window) but I need to use a button in the toolbar to switch to the different views.
How can I do that in a simple way?
Thanks
|
|
|
|
|
You can use tabs in a form view. There is an article in the Windows / Dialog section
http://www.codeproject.com/dialog/visualfx.asp
|
|
|
|
|
I found a much easier solution:
I have 2 member variables of CMainFrame (the 2 views):
CView* m_pScopeView;
CView* m_pXYView;
In CMainFrame::CreateClient, I do this:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
CRect ClientRect;
GetClientRect(ClientRect);
m_pScopeView = (CView*)new CExtScopeView;
m_pScopeView->Create(NULL, NULL, WS_CHILD, CFrameWnd::rectDefault, this, SCOPE_VIEW, pContext);
m_pScopeView->OnInitialUpdate();
m_pXYView = (CView*)new CXYView;
m_pXYView->Create(NULL, NULL, WS_CHILD, ClientRect, this, XY_VIEW, pContext);
m_pXYView->OnInitialUpdate();
SetActiveView(m_pScopeView);
m_pScopeView->ShowWindow(SW_SHOW);
m_pXYView->SetDlgCtrlID(XY_VIEW);
m_pScopeView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
RecalcLayout();
return TRUE;
}
And when I select another view:
void CMainFrame::OnXYView()
{
SetActiveView(m_pXYView);
m_pXYView->ShowWindow(SW_SHOW);
m_pXYView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
m_pScopeView->ShowWindow(SW_HIDE);
m_pScopeView->SetDlgCtrlID(fActiveView);
RecalcLayout();
fActiveView = XY_VIEW;
}
This work fine exept that the toolbar is drawn 1 or 2 pixels under the normal position and so, there's no separating line between the toolbar and the form view. This is very ugly!
How can I avoid this ???
Thanks
|
|
|
|
|
You should not explicitly be calling OnInitialUpdate() you are asking for trouble there. You should write your own initializing funnction in this case. In addition this does not look like an easier solution to me - the link I have takes care of some of the details. SHOW_WINDOW is the key to switching between the views, but you still must map to the frame window and handle messages properly.
|
|
|
|
|
Ok, but I found this method in a book.
I forgot to tell you that I'm using FormViews.
I don't want to have a tab: the user must choose on the toolbar wich view he wants to be displayed. There is 3 totaly different form views.
So is there any simple way to create the 3 views at the same time (and initialize them) and then switch to the one the user select ??
Thanks for your help
|
|
|
|
|
What you were doing would work. Just put the showwindow in the handler from the button.
|
|
|
|
|
Yes that works, except that the toolbar is not draw correctly... This is really ugly !
I used the debugger and I saw that the CFrameWnd::rectDefault rectangle has strange values:
top and left = -2147483648
bottom and right = 0
Is that normal ???
|
|
|
|
|
I don't know - I wouldn't be doing what you are doing in the first place so it is difficult to say. I think it is flawed from the beginning.
Either avoid Doc/View entirely or expect problems when you tinker with it. You should try to make sure you add at least the view that was passed in the argument list in oncreateclient, for example, and use the class editor to try to add it to the framework. You should also test things like loading multiple times with different views, test the MDU etc, drag and drop functionality. Read up on the document templates as well. There is no really simple way to change it because it is set up to take the complex task of doc / view and throwing in some more views. It should be set up by Microsoft to be easier to add multiple views - but the fact is that it isn't.
|
|
|
|
|