|
It very much depends on the compiler. I would actually expect an optimising compiler to generate the same code for A and C, and also the same code (possibly different from A/C) for B and D. B and D have an extra 'sequence point' according to the C++ specification, where all externally visible side-effects must be complete from evaluating the left side of || before any side-effects from the right-hand side are visible. However since they're just tests with no observable side-effects this rule doesn't really apply.
Atomic operations - operations that are all-or-nothing. Either the whole operation succeeds, or none of it succeeds. The term is usually used to mean that operations appear as if they occurred in a particular sequence. Assignment of simple, register-size values is an atomic operation - it cannot be broken up. However, incrementing is not atomic - the processor must read the existing value, increment it and write it back. Another thread could read the value before the write-back occurs, increment that and write it back. Two threads have tried to increment, but the value is only one greater than before.
The issue isn't relevant here, because you're only dealing with local variables and parameters, which will be on your thread's stack. It's very unlikely that another thread will be writing to those values. C and C++ offer no support for atomic operations. The most they provide is the volatile keyword, which tells the compiler that it must read from the memory location every time, it cannot cache the value in a register and reuse it.
They're all O(1). There's no polynomial complexity at all. The time taken will never vary (disregarding the possibility of system context switches, e.g. handling an interrupt, switching to a different thread) regardless of the value of n.
If you want to know more, I suggest compiling the code using the Listing generation options and examine the generated assembly.
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
OK, I loaded up VS2005 Beta 1 and pasted your code into a new project. In the same file I added main :
int a = A_Return_n_if_n_isIsLessThan2( argc );
int b = B_Return_n_if_n_isIsLessThan2( argc );
int c = C_Return_n_if_n_isIsLessThan2( argc );
int d = D_Return_n_if_n_isIsLessThan2( argc );
printf( "%d\n%d\n%d\n%d\n", a, b, c, d );
return 0; I then compiled with the /FAs option to generate assembly listings with source, using the Full Optimization, Favor Small Code options (/Oxs). A and C got compiled to the same code:
mov eax, DWORD PTR _n$[esp-4] ; eax = n
cmp eax, 2 ; set flags based on eax - 2
jb SHORT $LN4@C_Return_n ; jump if below
or eax, -1 ; set eax to -1
$LN4@C_Return_n:
ret 0 ; return, remove 0 items from the stack In reading this it's important to know that the eax register contains return value of the function. If the value is below 2 the jump is taken and eax already contains the return value. The compiler picked or rather than mov because it can use sign-extension to fill the whole register and therefore only needs to specify 0xFF rather than 0xFFFFFFFF for the mov instruction, saving 2 bytes (3 vs. 5).
B and D compile to this:
mov eax, DWORD PTR _n$[esp-4]
test eax, eax ; test sets the Zero Flag if zero
je SHORT $LN3@D_Return_n ; je (jump equal) jumps if ZF is set
cmp eax, 1 ; set flags based on eax - 1
je SHORT $LN3@D_Return_n ; if zero, jump
or eax, -1
$LN3@D_Return_n:
ret 0 Interestingly, the compiler actually removed the temporaries a , b , c and d from main and just compiled the calls inline, in the opposite order. Presumably the optimizer looked inside the calls, saw there were no side-effects, eliminated the sequence points that should have been at the end of each statement, and reordered the calls so it could push the results on the stack in the order needed for printf .
Therefore B/D might be slightly slower than A/C. However, on modern processors you can't count instructions and say the one with more instructions will be slower. You have to take parallel execution, out-of-order execution, and branch prediction into account. If enough resources are available the processor could evaluate the test , cmp and or in B/D in parallel, discarding the 'wrong' result. However A/C is smaller code and is more likely to fit on a memory page with other code, will fit better into instruction cache and uses fewer branch prediction resources. You're unlikely to see any difference, though.
There's very little point performing micro-optimisations like this unless you already know that there's a bottleneck here, which is pretty unlikely. Write whatever's clearest.
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
As others have said, A and C should compile down to the same code, and will probably be slightly quicker (maybe a nanosecond or so). However, just to throw a spanner in the works, a good compiler should be able to determine that all four are identical and produce identical code for every case. I don't know of any that would (check the Intel compiler though if you're interested - it has excellent optimisation).
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Hi,
I am using ATL to create a toolbar with a initially positioned static control in it with the following code in my Toolbar Class:
CWindow m_TextWindow;
LRESULT CToolbar::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
HWND m_Text = CreateWindow("STATIC", "Test Text", WS_CHILD | WS_VISIBLE, 465, 4, 15, 20, m_hWnd, NULL, NULL, NULL);
m_TextWindow.Attach(m_Text);
return 0;
}
In my OnSize function, I have the following code:
LRESULT CToolbar::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
RECT staticRect;
::GetClienRect(m_TextWindow, &staticRect);
staticRect.right -= 100;
return 0
}
However, I can not position the Static Control whenever I size the window.
Thanks in advance.
|
|
|
|
|
If I'm not mistaken, you need to actually call MoveWindow to get the control to move.
modified 12-Jul-20 21:01pm.
|
|
|
|
|
tdnxxx444 wrote:
However, I can not position the Static Control whenever I size the window.
That's because all you've done is changed the value of a variable. You need to call MoveWindow() or SetWindowPos() to actually move the window.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
ahhh.. Got it! Thanks for the help.
|
|
|
|
|
I have Visual Studio .NET but I'm programming in Win32 C++. I followed the procedure here and filled out the class wizard but once I click Finish, no files are created or anything. Am I missing something? I thought I ran into this problem before and it was some bug in VS. Thanks in advance.
|
|
|
|
|
Hi
I am creating a named pipe server with CreateNamedPipe(). Once a client connects, I use ImpersonateNamedPipeClient() and OpenThreadToken() to get the client's logon token. I then use LookupAccountSid() to get the client user account details. All standard stuff. *BUT* what I would like to do at this point is determine whether the client connected from a session logged on locally at the server, OR from another system. I *think* I need to check the logon type (LOGON32_LOGON_INTERACTIVE) but I have no idea how. Has anyone any idea how to do this?
Many thanks,
Neil Humphreys
|
|
|
|
|
I have a property sheet with lots of property pages.
Just before I launch the property sheet, I can type:
m_pViewPropertySheet->SetActivePage(1);
and that makes the first page active. I have alot of
helpful information on the 0th page; I have a button
on each property sheet that Im hoping that the end-user
can click on to switch them to the 0th property page.
I just can't get figure out the code to switch the user
from one property page to the another.
I could make a box popup that tells the user to go
click on the little tab at the top to switch to the
0th page for helpful information, but that's kinda
primitive.
I tried just letting the user figure out on their own
that the 0th page has lots of information, but they
never do.
Please, any response any one can give me will be
greatly appreciated.
Sincerely,
Danielle Brina (an overworked graduate student)
|
|
|
|
|
|
Can you show me how to use either command? I looked on
codeproject and google and dont see any examples.
Please, please, please. Im in lets say property page 2
and when they click on a button, I want to switch to
property page 1.
Please, please, please any response you can give me will
be greatly appreciated.
Sincerely,
Danielle Brina (an overworked graduate student)
|
|
|
|
|
Assuming MFC code (you didn't say what you were using), from the page 2 class, you can do something like:
CWnd* pSheet = GetParent();
pSheet->SendMessage ( PSM_SETCURSELID, 0, IDD_PAGE1 ); where IDD_PAGE1 is the resource ID of the page 1 dialog resource.
--Mike--
LINKS~! Ericahist | 1ClickPicGrabber | CP SearchBar v2.0.2 | C++ Forum FAQ | You Are Dumb
Magnae clunes mihi placent, nec possum de hac re mentiri.
|
|
|
|
|
is there any way to use CFileDialog to select an HTML file out of a resource DLL? I need to beable to select files out of a resource DLL and files in the filesystem.
-Steven Hicks
CPACodeProjectAddict
|
|
|
|
|
(Steven Hicks)n+1 wrote:
is there any way to use CFileDialog to select an HTML file out of a resource DLL? I need to beable to select files out of a resource DLL and files in the filesystem.
I can't see how this is possible as the standard File Open only looks on Disk. You could add a new Category and display these Resource entries yourself, but this is quite a lot of work. I do this in ED (see sig) to display File History, Include files etc. in the File Open dialog.
Neville Franks, Author of ED for Windows www.getsoft.com and Surfulater www.surfulater.com "Save what you Surf"
|
|
|
|
|
(Steven Hicks)n+1 wrote:
is there any way to use CFileDialog to select an HTML file out of a resource DLL?
Yes, but only if you write a shell namespace extension. It's probably more trouble than it's worth, and would be easier to write your own dialog box that looks and behaves similarly.
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Hello! Im fairly new to winsock programing, and am having trouble receiving a response that is spread accross several packets. I have been watching the communications through a packet sniffer, and know that 30 to 40 1500 byte sized packets are comming in with good data, but my program is only executing one recv and reporting a bytes Recv of 9. There must be some concept that im completely missing any help would be greatly appreciated.
heres my code:
bytesRecv = SOCKET_ERROR;
char queryRecvBuff[1500] = "";
CString reply = "";
send(m_socket,serverQuery,30,0);
TRACE("SENT\nRECEIVING:\n");
while( bytesRecv == SOCKET_ERROR ) {
bytesRecv = recv( m_socket, queryRecvBuff, 1500, 0);
if ( bytesRecv == 0 || bytesRecv == WSAECONNRESET ) {
TRACE( "Connection Closed in Auth.\n");
break;
}
if (bytesRecv < 0){
TRACE("\tbytes Recv < 0!!!");
return;
}
reply.Append(queryRecvBuff,bytesRecv);
TRACE( "\tBytes Recv: %ld\n", bytesRecv );
}
TRACE("\nRECEIVED");
output:
WAITING FOR Verification: VERIFIED
Sending Query: SENT
RECEIVING:
Bytes Recv: 9
RECEIVED
|
|
|
|
|
Knave777Wave wrote:
while( bytesRecv == SOCKET_ERROR ) {
bytesRecv = recv( m_socket, queryRecvBuff, 1500, 0);
I don't have all your code (ie. a server to send responses back) so I can't step through your code to really help you. But based on the code above:
SOCKET_ERROR is defined as having value -1
recv(...) is returning 9 bytes to you
This explains why the loop is only run once as bytesRecv will contain the value 9 which is not equal to -1 (SOCKET_ERROR).
As to if this is the proper value that is being recieved I don't know. If the first packet being sent from the server is of size 9 then this makes sense. Otherwise, I don't really know the reason.
Greba,
My lack of content on my home page should be entertaining.
|
|
|
|
|
thnx... i dont know what i was thinking
I switched it to a do--while w/ (bytesRecv != SOCKET_ERROR) and now i receive tons of packets and jump out of the loop with bytesRecv == 0.
Is this the normal behavior for such a transaction to end? Ive noticed several empty data packets being sent in the sniffer. Are these special packets that singal 'received' and so forth? If so, is my app receiving a special 'transfer done' packet that causes my last recv to unblock and return 0 bytes?
I dont know what the server is doing since it is not my app, its a particular games master server with a list of public game servers. I know all of this sounds pretty dumb, but this is a learning experiment where im trying to dive in a learn what is going on at the packet and app level.
thnx
|
|
|
|
|
Under the documentation of the recv function: "If the connection has been gracefully closed, the return value is zero". I'm assuming this would mean that the server has closed the connection. As to if this a correct or not assumption I don't know.
It doesn't sound pretty dumb, that is definitely a challanging and rewarding way to learn. If you still have problems with your recv, then I would suggest creating a server which emulates the behavior of the real server, and determine if you can send empty packets, and what happens when you close down a connection.
Greba,
My lack of content on my home page should be entertaining.
|
|
|
|
|
Anyone know how to do this?
ed
|
|
|
|
|
For example, suppose a project is composed of these 2 files:
//file1
extern int socket1;
//file2
int socket1;
Is possible to test for the existence of int socket1 during compilation if file2 is not part of the build, using some kind of compiler directives so that the project will compile/build normally?
|
|
|
|
|
A way to test for the existence of int socket1 in file1 would be use the preprocessor directives:
<br />
#ifdef socket1<br />
extern int socket1;<br />
#endif<br />
This will tell the preproccesor (what happens before compilation) to only use the code contained between "#ifdef socket1" and "#endif". If socket1 isn't defined (in file2) then the code between the preproccesor directives will not be compiled at all.
You will have to be careful though. Assuming you have code that used socket1 in file1 then you will get compile errors saying that socket1 isn't defined. To combat this you can do the following:
<br />
#ifdef socket1<br />
extern int socket1;<br />
#else<br />
int socket1;<br />
#endif<br />
I believe that answers your question.
Greba,
My lack of content on my home page should be entertaining.
|
|
|
|
|
jerry1211a wrote:
Is possible to test for the existence of int socket1 during co
Not directly, because the information you're looking for is not available at compile time, only link time. The extern int socket1 line tells the compiler "there's an int defined somewhere called socket1 " and that's all it needs. It's not until the linker comes along that the build process actually checks to see that socket1 is defined somewhere. That's why "unresolved external" errors are linker errors.
--Mike--
LINKS~! Ericahist | 1ClickPicGrabber | CP SearchBar v2.0.2 | C++ Forum FAQ | You Are Dumb
Magnae clunes mihi placent, nec possum de hac re mentiri.
|
|
|
|
|
I'm trying to catch F6 being pressed using 'OnKeyDown', but when F6 is pressed I get nothing. Keys F1, F2, F3, F4, F5 & F7 all work (I haven't tried the other function keys yet).
It's got me scratching my head, I even changed the keyboard, but it still does nothing. Any ideas?
Thanks,
Ali
|
|
|
|
|