std::min and 32/64 bits.

A

Andrea Venturoli

Hello.

I've got a style question...
Suppose I have the following code:

std::vector<X> V;
std::min(V.size(),1000u);

Now this will compile on 32b gcc, but not on 64b gcc.
So I can write:

std::vector<X> V;
std::min(V.size(),1000ul);

This will compile on 64b, but not on 32b.



Of course I can write:

std::vector<X> V;
std::min(V.size(),std::vector<X>::size_type(1000));

This will work on both platform.

However, not only I find this utterly ugly, but I feel it might make the
code harder to understand for the newcomer.


Is there any better way to achieve the above?


bye & Thanks
av.
 
V

Victor Bazarov

Hello.

I've got a style question...
Suppose I have the following code:

std::vector<X> V;
std::min(V.size(),1000u);

Now this will compile on 32b gcc, but not on 64b gcc.

Same with VC++ 2012 Express.
So I can write:

std::vector<X> V;
std::min(V.size(),1000ul);

This will compile on 64b, but not on 32b.



Of course I can write:

std::vector<X> V;
std::min(V.size(),std::vector<X>::size_type(1000));

This will work on both platform.

However, not only I find this utterly ugly, but I feel it might make the
code harder to understand for the newcomer.


Is there any better way to achieve the above?

Perhaps you could cast the return value of 'size' to what you need:

std::min(int(V.size()), 1000);

Unless, of course, you expect the size to be bigger than 2^31-1, then
cast to 'long long' or some such.

V
 
J

Jeff Flinn

Hello.

I've got a style question...
Suppose I have the following code:

std::vector<X> V;
std::min(V.size(),1000u);

Now this will compile on 32b gcc, but not on 64b gcc.
So I can write:

std::vector<X> V;
std::min(V.size(),1000ul);

This will compile on 64b, but not on 32b.



Of course I can write:

std::vector<X> V;
std::min(V.size(),std::vector<X>::size_type(1000));

This will work on both platform.

However, not only I find this utterly ugly, but I feel it might make the
code harder to understand for the newcomer.

std::min(V.size(),std::size_t(1000)); may be not as ugly?

Jeff
 
F

Fred Zwarts \(KVI\)

"Andrea Venturoli" wrote in message news:[email protected]...
Hello.

I've got a style question...
Suppose I have the following code:

std::vector<X> V;
std::min(V.size(),1000u);

Now this will compile on 32b gcc, but not on 64b gcc.
So I can write:

std::vector<X> V;
std::min(V.size(),1000ul);

This will compile on 64b, but not on 32b.



Of course I can write:

std::vector<X> V;
std::min(V.size(),std::vector<X>::size_type(1000));

This will work on both platform.

However, not only I find this utterly ugly, but I feel it might make the
code harder to understand for the newcomer.


Is there any better way to achieve the above?


bye & Thanks
av.

What about std::min<size_t>(V.size(),1000);

Is that still ugly?
 
A

Andrea Venturoli

What about std::min<size_t>(V.size(),1000);

Is that still ugly?


Thanks to everyone; I'll answer all in one message.

Jeff: using size_t instead of std::vector<X>::size_type is surely
shorter; however I don't think there is any guarantee they are the same
type.

Same goes for int, Victor.

I like Fred's solution: I hadn't thought about explicitly specifiying
std::min instance.

I'll try std::min<std::vector<X>::size_type>.

bye & Thanks
av.
 
V

Victor Bazarov

Thanks to everyone; I'll answer all in one message.

Jeff: using size_t instead of std::vector<X>::size_type is surely
shorter; however I don't think there is any guarantee they are the same
type.

Same goes for int, Victor.

My suggestion of casting to 'int' is based on the fact that '1000' has
that type.
I like Fred's solution: I hadn't thought about explicitly specifiying
std::min instance.

I'll try std::min<std::vector<X>::size_type>.

Definitely clearer and easier on the eye! ;-)

V
 
A

Andrea Venturoli

My suggestion of casting to 'int' is based on the fact that '1000' has
that type.

Right, but 1000 being an int was not my intention, really.


Definitely clearer and easier on the eye! ;-)

Not really, but less worse, perhaps.



bye & Thanks
av.
 
8

88888 Dihedral

Luca Risoliaæ–¼ 2013å¹´1月25日星期五UTC+8上åˆ2時20分34秒寫é“:
If I remember well, with regard to standard containers using standard

allocators, size_type ends up being a typedef of size_t, so you have

this guarantee in your case.



Anyway, I would use "std::min<decltype(V.size())>", which is good in the

general case.

As far as I know the vector in C++ is an indexed
homogeneous type of objects.

It is not a list of arbitrary types allowed
of objects with a GC built in.
 
8

88888 Dihedral

Luca Risoliaæ–¼ 2013å¹´1月25日星期五UTC+8上åˆ6時16分15秒寫é“:
Sorry, but I don't quite understand what you are talking about. My

answer was about size_t and size_type being the same type in a

particular case, which has nothing to do with the type of objects stored

in a vector or list or with a GC...







--- news://freenews.netfront.net/ - complaints: (e-mail address removed) ---


A vector of pointers of type void * is allowed in C++.

But it is very inconvenient to set up all different
items of objects in this way in C++.
 
B

Balog Pal

I'll try std::min<std::vector<X>::size_type>.

Sure, why use a single word of 6 letters when you can make it into 8
tokens with 25 overall length. O,O

Guess it's time to start the new school of 'Noise-oriented programming'.
 
A

Andrea Venturoli

Sure, why use a single word of 6 letters when you can make it into 8
tokens with 25 overall length. O,O

Because I never found a "guarantee" that std::vector<X>::size_type=size_t.

The fact that this usually is true is not enough in my case.

I'd be glad to change *if* I could be sure of the above.

bye & Thanks
av.
 
B

Balog Pal

Because I never found a "guarantee" that std::vector<X>::size_type=size_t.

The fact that this usually is true is not enough in my case.

Could you explain your case please? size_t has a well defined idea
behind it. For the cases discussed this far it shall cover the purpose,
even if some particularly evil implementation have chosen a different type.
I'd be glad to change *if* I could be sure of the above.

I'm not sure you want to be sure of the right thing.
 
A

Andrea Venturoli

Could you explain your case please?

Sure.
Both VC and GCC will warn about conversions (e.g. from long to int);
*hundreds* of warning in a compilation could lead to miss the important
ones.
So I've been asked to remove as much warnings as I can: I ofter turn the
relevant options off (e.g. -Wconversions in GCC), since most of these
are harmless, but I've been asked not to do this.


size_t has a well defined idea behind it.

Sure.
From what I found: "size_t corresponds to the integral data type
returned by the language operator sizeof".

I'd be glad to be proven wrong, but this has in principle nothing to do
with vectors (altough most implementation will use this type).
So the use of size_t *could* lead to a conversion warning (which is my
given goal to avoid).


For the cases discussed this far it shall cover the purpose,
even if some particularly evil implementation have chosen a different type.

In most cases, int will cover the purpose of letting the program run
flawlessly: when our vectors will be larger than 4G elements, we'll have
much more severe problems than some compiler warning.
However, as I said before, one of my tasks is to avoid them anyway.


I'm not sure you want to be sure of the right thing.

I don't follow... what do you mean?


bye & Thanks
av.
 
T

Tobias Müller

Andrea Venturoli said:
Sure.
From what I found: "size_t corresponds to the integral data type returned
by the language operator sizeof".

I'd be glad to be proven wrong, but this has in principle nothing to do
with vectors (altough most implementation will use this type).

It is the natural type for the size of a contiguous memory region. A vector
is exactly that.
However, sizeof is always the size in bytes. For packed representations
So the use of size_t *could* lead to a conversion warning (which is my
given goal to avoid).

Warnings are exactly for this. You make an assumption and if it proves
wrong you will be warned and you can fix it. But as long as you don't get
warnings on any of your supported platforms you're on the safe side.
Why do you want to get rid of warnings that don't occur anyway?

Tobi
 
A

Andrea Venturoli

Warnings are exactly for this. You make an assumption and if it proves
wrong you will be warned and you can fix it. But as long as you don't get
warnings on any of your supported platforms you're on the safe side.
Why do you want to get rid of warnings that don't occur anyway?

As I said before, because I've been asked to do so (by the persons who
pay me for my work).

bye & Thanks
av.
 
B

Balog Pal

Sure.
Both VC and GCC will warn about conversions (e.g. from long to int);
*hundreds* of warning in a compilation could lead to miss the important
ones.
So I've been asked to remove as much warnings as I can: I ofter turn the
relevant options off (e.g. -Wconversions in GCC), since most of these
are harmless, but I've been asked not to do this.

Well, that implies you work with a concrete set of compilers as the
environment. Not just shoot in the dark (like aim to release a general
library component claimed to be portable to the extremes).

For that case I see not enough reason to go paranoid and mess up the
code with excess noise. As you are pretty much able to verify that
size_t is good for your purposes. And have a plenty of ways to ensure it
too in form of a test, a static_assert, whatever.
Sure.
From what I found: "size_t corresponds to the integral data type
returned by the language operator sizeof".

It's also required to be unsigned in the C standard (7.17p2). And to
serve for sizeof it must be big enough to count bytes in the system. So
it must be good to count elements in a vector, maybe except for
vector<bool> that is a known troublemaker and better be avoided.

As size_type of std collections is also an unsigned integral, that is to
count the elements, I really don't see the problem place, and if one
actually shows up, I'd welcome the warning.
I'd be glad to be proven wrong, but this has in principle nothing to do
with vectors (altough most implementation will use this type).

I'd be very interested in a counter-example from the general world.
So the use of size_t *could* lead to a conversion warning (which is my
given goal to avoid).

I'd classify that is a mistaken goal -- the point is write good code,
that is easy to make right, and also easy to read and review. That is
obvious rather than cryptic.

Warinigs are our friend, that help the work. We make them go away by
writing *better* code. And in the few corner cases we encounter an
overzealous one, it's better be suppressed on the spot.
In most cases, int will cover the purpose of letting the program run
flawlessly:

int is not fit for purposes of size_t, and hardly fits this discussion.
when our vectors will be larger than 4G elements, we'll have
much more severe problems than some compiler warning.
However, as I said before, one of my tasks is to avoid them anyway.

And you stand with claim, that using the fixed size_t left you with
warnings?
I don't follow... what do you mean?

The wise saying goes "watch the baton not the runners". You look like
being after the wrong goal.
 
T

Tobias Müller

Andrea Venturoli said:
As I said before, because I've been asked to do so (by the persons who pay me for my work).

I seriously doubt that. It's usual that one tries to avoid warnings,
because they are noise that distracts from real bugs. But you gain nothing
by avoiding warnings never occur. The effect of this is just zero. You
can't see the difference because you don't have a setup where it actually
matters.

Tobi
 
Ö

Öö Tiib

Hello.

I've got a style question...

Style questions have usually more than one good answers. It is mostly matter
of taste with only minor amount of reasoning attached. I have seen rather nice
explanations to awfully cryptic (for my taste) styles like Hungarian Notation.
Suppose I have the following code:

std::vector<X> V;
std::min(V.size(),1000u);

Now this will compile on 32b gcc, but not on 64b gcc.

So I can write:

std::vector<X> V;
std::min(V.size(),1000ul);

This will compile on 64b, but not on 32b.

Of course I can write:

std::vector<X> V;
std::min(V.size(),std::vector<X>::size_type(1000));

This will work on both platform.

However, not only I find this utterly ugly, but I feel it might make the
code harder to understand for the newcomer.


Is there any better way to achieve the above?

This problem does not exist with my style. There may be others but this
is luckily gone:

1) I use style that requires template class instantiations to be typedefed. So:

typedef std::vector<X> Xes;
Xes V;

Reasoning: Most templates that can be used as alternatives in same place have
similar interface. Typedefing makes it easy to replace one type with other.
In given example to replace std::vector with std::deque only typedef has to be
edited. A good name clarifies the meaning of the type in context and it is often
shorter than template instantiation. typedef is also good spot where to document
the choice of particular template (why vector?) further if needed.

2) I use style that requires numeric constants to be named. Only 0 and 1 may
be used unnamed if it makes more sense than using names. Those two have
myriad of language-defined names already (like NULL, false, nullptr,
EXIT_SUCCESS etc.). So:

Xes::size_type const VLimit = 1000;

Reasoning: Name explains the meaning of constant, definition creates good spot
where to further document it. Also it is possible to modify it from one place
if the constant happens to change. Note that thanks to typedef it is clear to
understand what it is meant for.

As result your problem is removed, the code works everywhere:

std::min( V.size(), VLimit );
 
S

Seungbeom Kim

I seriously doubt that. It's usual that one tries to avoid warnings,
because they are noise that distracts from real bugs. But you gain nothing
by avoiding warnings never occur. The effect of this is just zero. You
can't see the difference because you don't have a setup where it actually
matters.

I'm not speaking for the OP's case, but in a very general sense, you
may not know the exact set of possible target platforms in advance.
If you're committing the code to a public repository, you never know
who will use it on which platforms. Even you could upgrade the system
and see new warnings occur.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top