|
i have this code and it works fine.
int fatt(int n)
{
int fattoriale = 1;
if(n==0)
return fattoriale;
else
return fattoriale=n*fatt(n-1);
}
void main(void)
{
printf("%d\n",fatt(10));
fflush(stdin);
getchar();
}
my question is why it works fine also here ?
int fatt(int n)
{
int fattoriale = 1;
if(n==0)
return fattoriale;
else
fattoriale=n*fatt(n-1);
}
void main(void)
{
printf("%d\n",fatt(10));
fflush(stdin);
getchar();
}
in this, there aren't the return in the else.... i am using VS2010 and compile in .c .
thanks
ps: sorry for my english
|
|
|
|
|
In release mode it will create compilation error. It creates compilation error in VS2008. I got compilation error "error C4716: 'fatt' : must return a value".
But in debug mode it works as follows.
In both case contents of EAX register is used as the output of fatt() function. In both case EAX holds the output value, therefore the two versions works correctly in debug mode.
The result of imul is available in eax register and that is the expected result from the fatt function.
Following are the disassembly of two versions of fatt() function. First one with return value and next is without return value.
return fattoriale=n*fatt(n-1);
01182ED2 mov eax,dword ptr [n]
01182ED5 sub eax,1
01182ED8 push eax
01182ED9 call fatt (1181889h)
01182EDE add esp,4
01182EE1 imul eax,dword ptr [n]
01182EE5 mov dword ptr [fattoriale],eax
01182EE8 mov eax,dword ptr [fattoriale]
fattoriale=n*fatt(n-1);
01182F92 mov eax,dword ptr [n]
01182F95 sub eax,1
01182F98 push eax
01182F99 call fatt (11815FAh)
01182F9E add esp,4
01182FA1 imul eax,dword ptr [n]
01182FA5 mov dword ptr [fattoriale],eax
The multiplication in n*fatt(n-1) is done with imul operation. And its output is available in EAX register.
In first version( with return statement), last two instructions perform the following things. Contents of eax is moved to fattoriale and after that the contents of fattoriale is moved to eax( EAX holds the return value, or result of operation).
In second version( without return statement) the last mov is not found. But the output of iMul is in EAX register and therefore the output will be available to caller function through EAX register.
|
|
|
|
|
Your explanation is nice but do you expect a beginner in c to understand x86 assembly?
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
|
|
|
|
|
The point is that values are returned in the eax register. The mathematical operation happens to end up with the result in eax AND eax isn't changed by any other operation. Thus it returns the right value. Problem is that something like an inline optimization could change that.
|
|
|
|
|
Thanks to all! I understood!
|
|
|
|
|
Without the 'else' the program flow just goes to the end of the func and returns. However there is no return value, so anything calling fatt() and expecting a return value if the 'else' path is hit is going to be dissapointed.
modified 15-Jul-13 9:01am.
|
|
|
|
|
For me, both in Debug and Release mode, the compiler (VS 2010) issues a warning for the second version, indicating the problem.
I have set Warning level to 3, and I've found that the majority of Warnings at that level indicate true errors.
My advice to beginners is:
1. Set Warning level to at least 3 (but see link below)
2. Make sure you first understand the true meaning of each Warning and what kind(s) of problem(s) it could cause at runtime. Then fix it.*
Here's an interesting article on how to deal with warnings, including those that are off by default[^].
|
|
|
|
|
I'm intending to make a program that erase an HDD. I know that modern HDDs relocate potentially deffective sectors by SMART testing, and replace with other not normally accessible. Is there a way to access ALL the sectors?
VII. 36. When you surround an army, leave an outlet free. Do not press a desperate foe too hard.
SUN-TZU - Art of War
|
|
|
|
|
Relocation (remapping) is done transparently by the disk firmware. When a sector is detected as bad, all it's data are transferred to a special reserve area called sparse area and all further read/write attempts are redirected to it. See this wikipedia article.[^]
Sparse areas are not accessible using any standard disk access methods as all LBA addressing to it automatically redirected. (But, it is possible that there may be some vendor-specific commands to do that)
*TIP: You can use ATA Secure Erase[^] command to perform a firmware level erase of disk sectors. The GNU Shred utility is a noteworthy program using this command.
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
|
|
|
|
|
Thanks a lot. Been a SunTzu fan I also like Clausewitz very much!
VII. 36. When you surround an army, leave an outlet free. Do not press a desperate foe too hard.
SUN-TZU - Art of War
|
|
|
|
|
In a project, I use the CMainFrame* pMainFrame = new CMainFrame() to create a main frame.
When the function CMainFrame::OnNcDestroy is called, void CView::PostNcDestroy()
will be called. I donot know why CView::PostNcDestroy() will be called, in the function CFrameWnd::OnCreateClient()
no new CView is created. Is there anyone know why? Thanks. 
|
|
|
|
|
Use your debugger. As a first step I would put a breakpoint into CView::PostNcDestroy() and check out the callstack. There you will see who calls it and if you are lucky you can track back the reason. As a second try I would keep track of the creation of every CView and then find out which one is getting deleted.
|
|
|
|
|
|
Thinking about the fork-exec model used common in Unixes. Windows doesn't have a fork() but has all exec() counterparts. So, how does windows behave in this case? Is it similar to unix (shared ds, open fd's etc.) or in a different way?
Ans: Exec is complete alien in windows. It spawns a new process.
Tried googling but answers came mostly about unixes
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
|
|
|
|
|
|
Richard MacCutchan wrote: In windows you create processes and/or threads[^].
I'm afraid, that's not what I asked. Being a windows developer I'm aware of the model used in windows.
Ok, then let me put my case here: I have a small unix app (written many many days ago) and now, I want to run it on windows. It has a certain case when it executes another executable with an exec() family call. This replaces the entire process with the child process, including the PID. Is this possible with the exec() family under windows?
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
|
|
|
|
|
|
Before posting this message I also went through that page, but couldn't make anything out of it, because of my .NET background.
Only thing that caught my eyes was this:
A program executed with one of the _exec functions is always loaded into memory as if the maximum allocation field in the program's .exe file header were set to the default value of 0xFFFFH.
Can you explain what it does? Creates a new, detached porcess or replaces it just like unix.
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
|
|
|
|
|
First sentence: Each function in this family loads and executes a new process.
You can use this either to launch an independent process that will run to completion with no interaction from the original, or you can connect to its stdin/out files for communication, or just wait for it to complete and check status. I think you can use the System.Diagnostics.Process[^] class in .NET in a similar manner.
Use the best guess
|
|
|
|
|
Thank you.
Beauty cannot be defined by abscissas and ordinates; neither are circles and ellipses created by their geometrical formulas.
Source
|
|
|
|
|
Unix like fork is quite foreign in windows. Cygwin simulates fork on windows: http://stackoverflow.com/questions/985281/what-is-the-closest-thing-windows-has-to-fork[^]
There are many "unix simulation libraries" available on windows (including cygwin, interix, ...) but I wouldn't recommend building on top of these if you don't have to. My opinion about the cygwin fork simulation: In the unix world many tools/scripts make use of spawining other processes and processing data by piping the output of one process to another process. Running the same script/program "network" on windows/cygwin is multiple times slower than running the same command on linux if it involves a lot of fork invocations (for example a simple ./configure and ./make combination is always much faster on linux).
|
|
|
|
|
It is similar and different.
|
|
|
|
|
Using VS2008 Professional (v 9.02) in Debug mode on Windows 8 to write a Win32 program I have two versions of Windows Common Controls ComCtl32.dll loading. On a call to: CreateDialogParam one: Product Version 6.2.92.../File Version 5.82.92... loads then on a call to SetupDiGetClassImageList another one loads having Product Version 6.2.92.../File Version 6.10.92.
I only noticed when having problems trying to use a feature of ListView header (up/down sort arrows) that various Googled sources attribute to needing a later version of ComCtl32.dll.
I had a look at the Manifest but see nothing seems relevant there. Switching to Release mode had no effect.
Is it possible to just load one version, preferably the later version loading?
The above with slightly more detail from the VS Output window is below for reference if needed.
In Debug mode:
Between:
hSelectDlg = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_DIALOG_SELECT), 0, DialogProc, 0);
and entering
BOOL CALLBACK DialogProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Loaded 'C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.9200.16384_none_bf100cd445f4d954\comctl32.dll'
then on a call:
BOOL b = SetupDiGetClassImageList(&m_spImageData);
Loaded 'C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.9200.16579_none_8937eec6860750f5\comctl32.dll'
|
|
|
|
|
Hi,
Have you tried adding a /MANIFESTDEPENDENCY entry for common controls specifying version six and above? Follow the instructions here:
Enabling Visual Styles[^]
Best Wishes,
-David Delaune
|
|
|
|
|
David,
No I hadn't tried anything in the manifest. I've had a quick scan of the link you set and (initially)took the quick option of pasting in the example #pragma just as it's given for a version version= '6.0.0.0' to set the version from a .h file. No obvious difference yet as its still loading a v5 and a v6.
Of relevancet, I have a WTL/ATL version that I can step through side by side with the Win32 version and the WTL/ATL only loads one ComCtl32.dll, the v6.
I'll have a look in more detail later.
Thanks
... controls_6595b64144ccf1df_5.82.9200.16384_none_bf100cd445f4d954\comctl32.dll
...
... controls_6595b64144ccf1df_6.0.9200.16579_none_8937eec6860750f5\comctl32.dll
|
|
|
|