we have been using an int type for both dates in the format YYYYMMDD and
number of days to some date.
We've had issues where both types got mixed at runtime.
We're looking for a simple C++ fix to this if there is, something like:
struct Date {
int i;
};
struct Days {
int i;
};
void f( Date d );
...
const Days d = { 15 };
f( d ); // compile-error
This would help detect at compile-time errors like these.
Is there a runtime cost of using struct instead of int, in these cases?
regards,
On a simple example, there doesn't seem to be on my compiler (VC++2005)
at least, judging by the disassembly (see both below). The key thing to
note is that the generated assembly code is the same in both cases - so
they're doing the same thing and thus have the same runtime cost.
Out of interest, though:
- Why are you worrying about the runtime cost of using a Date struct?
Its chances of causing a performance bottleneck in your code seem quite
low (if you haven't profiled and identified that it's a problem, then
it's not something you should really be concerned with optimizing).
- Why are you rolling your own date implementation?
Best wishes,
Stu
struct X { int i; };
void f(int& i)
{
i = 9;
}
void g(X& x)
{
x.i = 9;
}
int main()
{
int i = 23;
X x = {23};
f(i);
g(x);
return 0;
}
***
void f(int& i)
{
004113B0 push ebp
004113B1 mov ebp,esp
004113B3 sub esp,0C0h
004113B9 push ebx
004113BA push esi
004113BB push edi
004113BC lea edi,[ebp-0C0h]
004113C2 mov ecx,30h
004113C7 mov eax,0CCCCCCCCh
004113CC rep stos dword ptr es:[edi]
i = 9;
004113CE mov eax,dword ptr [i]
004113D1 mov dword ptr [eax],9
}
004113D7 pop edi
004113D8 pop esi
004113D9 pop ebx
004113DA mov esp,ebp
004113DC pop ebp
004113DD ret
void g(X& x)
{
004113E0 push ebp
004113E1 mov ebp,esp
004113E3 sub esp,0C0h
004113E9 push ebx
004113EA push esi
004113EB push edi
004113EC lea edi,[ebp-0C0h]
004113F2 mov ecx,30h
004113F7 mov eax,0CCCCCCCCh
004113FC rep stos dword ptr es:[edi]
x.i = 9;
004113FE mov eax,dword ptr [x]
00411401 mov dword ptr [eax],9
}
00411407 pop edi
00411408 pop esi
00411409 pop ebx
0041140A mov esp,ebp
0041140C pop ebp
0041140D ret
int main()
{
00411410 push ebp
00411411 mov ebp,esp
00411413 sub esp,0D8h
00411419 push ebx
0041141A push esi
0041141B push edi
0041141C lea edi,[ebp-0D8h]
00411422 mov ecx,36h
00411427 mov eax,0CCCCCCCCh
0041142C rep stos dword ptr es:[edi]
int i = 23;
0041142E mov dword ptr [i],17h
X x = {23};
00411435 mov dword ptr [x],17h
f(i);
0041143C lea eax,[i]
0041143F push eax
00411440 call f (4111DBh)
00411445 add esp,4
g(x);
00411448 lea eax,[x]
0041144B push eax
0041144C call g (4111D6h)
00411451 add esp,4
...
> struct Date {
> int i;
> };
>
> struct Days {
> int i;
> };
>
>
> void f( Date d );
>
> ...
> const Days d = { 15 };
> f( d ); // compile-error
>
It's because you tried to pass a "const Days &"
to a "Date", and a "const Days &" cannot be converted to a "Date".
I think that was what he wanted it to do in that case: not compile. He's
introducing two different types for dates and days so that instances of
one can't be passed to functions which expect the other. When both were
just a typedef for int, that wasn't the case.
Stu
As far as I know, none worth mentioning, if you do it reasonably well.
It's important for a C++ compiler to make this cheap: the standard
library iterators etc need it to compete with raw pointers.
But -- your solution is a C solution. That's painful. Why not
class Days {
public:
Days() : d(0) {}
explicit Days(int days) : d(days) {}
// operators etc which make sense, e.g.
// output, addition and ++, but not multiplication
private:
int d;
};
const Days d(15);
Otherwise, I definitely agree with you. Typedef:ing ints is just
asking for the kind of problem you describe. Also see this discussion,
"Simple and clear ways of creating distinct types":
Message-ID: <slrngmma6s.c...@frailea.sa.invalid>
/Jorgen
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Date should be a class. Valid values of Date are a subset of int and
you can use the constructor to enforce validity. But it sounds like
days really is just an int as far as I can tell from your post.
HTH