|
Mark Salsbery wrote: Why not?
Unless I'm missing something, you can't do this:
extern int BufferSize;
#include "SynthToolkit.h"
class SomeClass
{
private:
buffer[BufferSize];
};
The reason, I'm guessing, is that the compiler can't resolve the size of "BufferSize" at compile time, so it doesn't know the size of the array.
|
|
|
|
|
But he didn't it. He declared BufferSize as const .
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
CPallini wrote: But he didn't it. He declared BufferSize as const.
Leaving out const was a typo on my part. I stand by my original point. An integer constant with external linkage can't be used to declare the size of an array at compile time.
I would love to be corrected on this if I'm wrong.
|
|
|
|
|
You're correct You'll need a constant, so again, the second
method is better.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Leslie Sanford wrote: I stand by my original point. An integer constant with external linkage can't be used to declare the size of an array at compile time.
You can use it in the source file (there must be one) that defines (assigns) the const variable.
Anyway, on the overall, you're right.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
CPallini wrote: You can use it in the source file (there must be one) that defines (assigns) the const variable.
Anyway, on the overall, you're right.
Ah, I see what you mean. With internal linkage, the integer constant can be used to determine the size of an array at compile time. My declaration that it "doesn't work" was too broad. It does work with internal linkage, but not external.
Thanks for the clarification. I've learned something new.
|
|
|
|
|
Using a different name is not possible?
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Good question!
How was this conflict avoided up 'til now?
Why is it coming up now?
|
|
|
|
|
Member 754960 wrote: How was this conflict avoided up 'til now?
Why is it coming up now?
I've been tying in the GUI code, which is Windows based, to the non-GUI code, which is agnostic about what platform it's on.
|
|
|
|
|
OK. As that would be a different discussion, I'll only say that I would try to maintain that separation.
As for the macro, you should be able to define the constant directly in the header file,
const int BufferSize = 16384;
The compiler should accept this when defining your arrays,
void f()
{
char buf[Buffersize];
}
and the linker should resolve multiple references in files just as it would with any other constant.
The question then becomes if this constant needs to be exposed outside of the non UI code and hence in a project wide include file. Is the intent that the standard application bufer size is a constant or just those of the non UI code? Why should any other module know this?
|
|
|
|
|
I prefer enum for any class scope integer constants.
class SynthToolKit
{
public:
enum Size {
enBufMax = 1684,
enBufMin = 12
};
};
bool OtherKit::Test()
{
p = new UCHAR[SynthToolKit::enBufMax];
}
Maxwell Chen
|
|
|
|
|
Maxwell Chen wrote: I prefer enum for any class scope integer constants.
Thanks!
I hadn't thought about using enums. I can use that for global scope integer constants, too:
[code]
enum SynthToolkitConstants
{
BufferSize = 16384
};
[/code]
I don't know if this is considered bad style, but it certainly solves my compiling problems.
|
|
|
|
|
Leslie Sanford wrote: don't know if this is considered bad style
This is a good style. The enum s act as a combination of const ants and #define itions, and enum s can be types. And you can group the values.
class ToolKit
{
public:
enum Size {
enBufMin = 12,
enBufMax = 1024
};
enum Pos {
enTop,
enRight,
enLeft
enBottom
};
bool Alloc(Size val) {
return true;
}
};
Maxwell Chen
modified on Sunday, January 13, 2008 1:16:57 PM
|
|
|
|
|
AFAIK, the only reason for this style is a compiler limitation. The language allows a class constant definition but the MSVC compiler (for one) doesn't handle it. I have yet to see if the latest version does though. I seem to recall that using enums for constants is somewhat frowned upon; common practice though.
|
|
|
|
|
Member 754960 wrote: AFAIK, the only reason for this style is a compiler limitation. The language allows a class constant definition but the MSVC compiler (for one) doesn't handle it.
Actually you can use a class const, i.e. a const static member.
Member 754960 wrote: I seem to recall that using enums for constants is somewhat frowned upon
Why?
Member 754960 wrote: common practice though.
Of course (however enums have limitation, for instance they cannot be used for floating pointer consts).
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
[my articles]
|
|
|
|
|
I just tested this with the MSVS Team Server (MSVC 9) and, yes, you can define a class constant,
class A
{
static const int MAXBUFFERLEN = 1024;
char szBuffer[MAXBUFFERLEN];
public:
A() {}
~A() {}
};
which is a Good Thing seeing as I already claimed it. Which is "better" than declaring it then defining it in the *.cpp file.
Why are the enum less desireable? I would have to seek it out again but what springs to mind is type. Enumerations are types and should be treated as such and not as substitutes for something else. It may not be so but I would expect the compiler to complain if I substituted a enumerated value for an integer,
enum WeekDays
{
Monday = 0,
Tuesday = 1,
Wednesday = 2,
Thursday = 3,
Friday = 4,
Saturday = 5,
Sunday = 6,
NumberofWeekDays = 7
};
int Workdays[5];
void f()
{
int i = Workdays[Monday];
i = Monday;
}
Implicit conversion resolves this but should it? There is also the issue of invalid convesion. What does this mean:
void f(WeekDays aDay) {}
void g()
{
f(WeekDays(24));
}
When I first learned enumerations I learned never to count on their value. That may be out of date now but it strikes me how many applications will fail if the order or value of the enumerations changes. Very fragile. (Yet, at work we use this technique extensively; because we have to.) As a type, this seems contrary to what is desired. I want consistency and predictability. Monday comes before Tuesday; by how much doesn't matter. I can't multiply Monday by any value and get Friday. I can't make a Weekday from a sow's ear.
YMMV
|
|
|
|
|
Basically enum serves for state machine and option stuffs.
class ToolKit
{
enum State {
st_Idle,
st_Init,
st_Tx,
st_Rx,
st_Swap,
st_More
};
State m_State;
protected:
bool ThreadProcedure() {
switch(m_State) {
case st_Init:
break;
}
return true;
}
public:
bool OnButtonClickInitialize() {
if(Busy()) {
return Reject();
}
return NewTask(st_Init);
}
};
Maxwell Chen
|
|
|
|
|
Member 754960 wrote: a compiler limitation. The language allows a class constant definition but the MSVC compiler (for one) doesn't handle it.
If I recall correctly, ISO C++ (1997) supports class constants, but MSVCs haven't been quite handling this well. Older versions of MSVCs just supports static const members. (But I haven't checked this with 2008.)
class ToolKit
{
public:
const int n = 10;
};
class ToolKit
{
public:
ToolKit() : n(10) { }
const int n;
};
Maxwell Chen
|
|
|
|
|
You're right. This works in MSVC 9 and you can use the constant in the class declaration.
|
|
|
|
|
Wait!! These two are different as below!
1.
class ToolKit
{
static const int a = 5;
};
2.
class ToolKit
{
const int a = 5;
};
Maxwell Chen
|
|
|
|
|
Hi Leslie,
AFAIK you are supposed to follow a strict order in your #define and #include lines,
basically Windows headers should come first, third-party headers second, everything else
after that.
The official reason is newer Windows releases may modify or add to the header files
and suddenly create conflicts; of course this still can happen in the suggested order too,
but then it more looks like the problem is yours...
BTW: you can protect yourself against some mishaps by doing an #undef before you
do your own #define (you can #undef an undefined item, that does not constitute an error).
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|
My application's primary interface is a notify icon in the systray.
If explorer.exe crashes, then the app's notify icon doesn't come back when the taskbar reappears.
However, some applications' icons do come back such as the Avast anti-virus, and SQL Server.
Is it possible that these other apps are receiving some sort of notification to recreate their icons?
The client might ask me to fix this by claiming it's a bug, which I would disagree with.
Do you think this can be classified as a bug? How is it that those other apps' icons are able to come back when explorer.exe restarts?
“Cannot find REALITY.SYS...Universe Halted.”
~ God on phone with Microsoft Customer Support
|
|
|
|
|
See the Extras section of this article.
"Normal is getting dressed in clothes that you buy for work and driving through traffic in a car that you are still paying for, in order to get to the job you need to pay for the clothes and the car and the house you leave vacant all day so you can afford to live in it." - Ellen Goodman
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Thanks! You saved me!
“Cannot find REALITY.SYS...Universe Halted.”
~ God on phone with Microsoft Customer Support
|
|
|
|
|
In addition to DavidCrow's reply....
On Vista, you may need to use ChangeWindowMessageFilter() to
get your app to receive the TaskbarCreated message in certain
situations.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|