|
|
It won't be commented out nor does it need to be. I take it he is just using the commenting out to show whats there.
Assuming it uncommented it's an extern (which is nothing more than a forward prototype) with a macro calling the extern. That won't create any problem at all as there is clearly no function body provided in hmacros.h by doing that and it will simply defer to the extern body provided with one big proviso that the prototype matches the external body declaration.
I am still backing that BYTE gets defined differently (probably inside hmacros.h) and so the prototype doesn't match the body. We know BYTE must be defined prior to CPU.C using it and CPU.C then includes hamacros.h. I am betting hmacros.h defines BYTE as well (probably one is as a char and one as unsigned char).
Given that the compiler is seeing no macro redefinition etc it's clear one will be #define BYTE ... and the other typedef so BYTE has two valid but different definitions which don't on their own clash.
Here try it
typedef unsigned char BYTE;
void hex_to_ascii(BYTE *ipx, char *str, int num);
#define BYTE char
void hex_to_ascii(BYTE *ipx, char *str, int num) {
};
That is illegal in C especially if one is declared extern, the header and the body don't match because they are using different versions of BYTE. In C++ it would overload and then tell you one of your overloads hasn't got a body definition. Remove the macro and it will compile correctly because the forward declaration and body match then.
It's dead easy to do and one of the normal problems of merging multiple libraries who like to make there own definitions.
In vino veritas
modified 20-Dec-16 1:56am.
|
|
|
|
|
If BYTE is defined differently between the forward declaration and the definition, you certainly wouldn't get a "redefinition" error.
|
|
|
|
|
It's not the prototype and body that causes the problem it's the syntax to do it ... try it
#define BYTE char
#define BYTE unsigned char
You also can't have two typedefs try that as well
typedef char BYTE
typedef unsigned char BYTE
You also must have the typedef first and the macro second, try this reverse case and see what happens
#define BYTE char
typedef unsigned char BYTE
It is very specific and very annoying and painful, but it is that order typedef followed sometime later by a macro. Hence I know the order that it must be in.
Seen it and done it a number of times and it's really really annoying and makes you scratch your head.
In vino veritas
modified 23-Dec-16 12:49pm.
|
|
|
|
|
That gives you an error on the redefinition of the macro... has nothing to do with using it in a function prototype. If the definition of a macro was changed in between forward declaration and definition, you'd get a different error, such as "symbol not found" when you try to use it.
|
|
|
|
|
No you don't ... think about it and just rewrite what it expands to
This is what you have
typedef unsigned char BYTE;
void hex_to_ascii(BYTE *ipx, char *str, int num);
#define BYTE char
void hex_to_ascii(BYTE *ipx, char *str, int num) {
};
Expanded removing BYTE and replacing the type that is in scope it becomes ... dead simple
Remember the macro is in the preprocessor which is why it always expands like this, and why the second BYTE is gone by compile time. The first BYTE remains (it is prior to the macro definition), and I strike it out and changed it to it's proper type.
void hex_to_ascii( (BYTE) unsigned char *ipx, char *str, int num);
void hex_to_ascii(char *ipx, char *str, int num) {
};
Get it your forward prototype and function body no longer match.
Depending on the C compiler it can see it as
1.) Two different functions with the same name .. THAT IS AN ERROR
2.) The same function with mismatched or redefined types ... THAT IS AN ERROR
Which depends how good your compiler is and there is no standard answer to what it will say. It even depends if they are in the same files or not because the compiler is trying to guess what you are meaning to do. His example complicates it because he has an extern in a 3rd file which I think means the compiler doesn't have a clue whats going on it's got 3 prototypes probably only 2 matching.
As I said you are arguing about something that is easy to test and I have seen many times when joining multiple libraries together.
In vino veritas
modified 23-Dec-16 14:59pm.
|
|
|
|
|
How can I create MFC application code to move a train in two directios
|
|
|
|
|
Well code doesn't move trains, they have engines, usually.
In other words, if you want better help then should better detail your scenario.
|
|
|
|
|
Just out of curiosity, how did you arrive at the need for MFC?
"the debugger doesn't tell me anything because this code compiles just fine" - random QA comment
"Facebook is where you tell lies to your friends. Twitter is where you tell the truth to strangers." - chriselst
"I don't drink any more... then again, I don't drink any less." - Mike Mullikins uncle
|
|
|
|
|
I bet you really know the answer to that.
|
|
|
|
|
Busted!
"the debugger doesn't tell me anything because this code compiles just fine" - random QA comment
"Facebook is where you tell lies to your friends. Twitter is where you tell the truth to strangers." - chriselst
"I don't drink any more... then again, I don't drink any less." - Mike Mullikins uncle
|
|
|
|
|
Start by creating an MFC application to move a train. Then add code to move it in one direction. After that, add code to move it in two directions.
Q: How do you eat an elephant?
A: One bite at a time.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
it's impossible.
the compiler spins horizontally and the MFC Overwatcher spins vertically, and together these will spin the locomotive engine right off the track.
|
|
|
|
|
|
The question is so bad that"By using computer, keyboard and mouse" can be an answer.
try to refine the question.
Patrice
“Everything should be made as simple as possible, but no simpler.” Albert Einstein
|
|
|
|
|
MFC doesn't stand for 'Moves Freight and Carriages' you know.
|
|
|
|
|
Can someone send me a code with an implementation of the original version of Tiny Encryption Algorithm with simple encryption and decryption of texts. Thank you!
|
|
|
|
|
|
No multiple Repost in multiple forums, Please.
Patrice
“Everything should be made as simple as possible, but no simpler.” Albert Einstein
|
|
|
|
|
Hi all of you. I have a dialogbar from where I open a popup dialog, let say CMyDialog , but it is opened in non modal way, dynamically created:
void CDialogBar::SomeButton()
{
CMyDialog* pDialog = new CMyDialog;
pDialog->Create(...);
}
From that dialogbar, it is possible to know if that CMyDialog is opened ?
void CDialogBar::OtherButton()
{
CWnd* pWnd = FindWindowEx(NULL, NULL, _T("Dialog"), NULL);
ASSERT(NULL != pWnd);
}
but the pWnd is always NULL, even when CMyDialog is open ...
How can I know for sure if that CMyDialog is opened, without making pDialog as member variable of CDialogbar ?
|
|
|
|
|
Check that you class name is correct for an MFC Dialog. you should also try to provide values for as many of the parameters as possible.
[edit]
See About Window Classes (Windows)[^] for correct system class names.
|
|
|
|
|
See the hwndParent parameter at FindWindowEx function (Windows)[^]:
Quote: If hwndParent is NULL, the function uses the desktop window as the parent window. The function searches among windows that are child windows of the desktop. You did not show us the full Create call but if you have passed CDialogBar or any other window of your application as parent you must also pass it to FindWindowEx (using this for the CDialogBar here):
CWnd* pWnd = FindWindowEx(this->GetSafeHwnd(), NULL, _T("Dialog"), NULL);
But you should think about using a member variable. The only thing to do then is clearing the pointer when the dialog is closed. Otherwise you have to check for existance also in your SomeButton function to avoid creating multiple instances of your dialog.
|
|
|
|
|
The creation of CMyDialog is:
pMyDialog->Create(CMyDialog::IDD, this);
I will try your advice, I hope to work.
"But you should think about using a member variable. The only thing to do then is clearing the pointer when the dialog is closed. Otherwise you have to check for existance also in your SomeButton function to avoid creating multiple instances of your dialog."
The CMyDialog could have only one instance, so, there is no problem with that.
|
|
|
|
|
Flaviu2 wrote: The CMyDialog could have only one instance, so, there is no problem with that. How do you know that?
If CDialogBar::SomeButton is called again (the name indicates that it requires only a mouse click), you would have multiple instances. When using a member variable you could then activate the existing dialog instead of creating a new one.
|
|
|
|
|
The CMyDialog are closed when he lost the focus, so, there is no way to be two (or more) instances.
|
|
|
|