[serialize] struct save_array_type in oserializer.hpp

Hi, Is there a reason to use type int in the code at line 487 in oserializer.hpp? int count = sizeof(t) / ( static_cast<const char *>(static_cast<const void *>(&t[1])) - static_cast<const char *>(static_cast<const void *>(&t[0])) C++ standard draft states in section 5.3.3 [expr.sizeof] The result is a constant of an implementation-defined type which is the same type as that which is named size_t in the standard header <cstddef>(18.1). WBR Oleg V. Zhylin ovz@yahoo.com ____________________________________________________________________________________ 8:00? 8:25? 8:40? Find a flick in no time with the Yahoo! Search movie showtime shortcut. http://tools.search.yahoo.com/shortcuts/#news

On Wed, April 11, 2007 17:51, Oleg V. Zhylin wrote:
Hi,
Is there a reason to use type int in the code at line 487 in oserializer.hpp?
int count = sizeof(t) / ( static_cast<const char *>(static_cast<const void *>(&t[1]))
- static_cast<const char *>(static_cast<const void *>(&t[0]))
C++ standard draft states in section 5.3.3 [expr.sizeof]
The result is a constant of an implementation-defined type which is the same type as that which is named size_t in the standard header <cstddef>(18.1).
I assume otherwise you will get a warning, that a sign can be lost through the assignment. The problem here is that expression (type* - type*) results not in an unsigned type (size_t) but a signed difference type. If you divide unsigned value through a signed value you get a signed value. And then you would (according to your suggestion) assign it to an unsigned value => warning. With Kind Regards, Ovanes Markarian

At least for VC7.1 compiler int a, b; cout<<typeid(sizeof(a)/(a - b)).name()<<endl; prints "unsingned int" and issues no warnings about int -> size_t conversion. Thus I still wonder if usage of int type in
int count = sizeof(t) / ( static_cast<const char *>(static_cast<const void
*>(&t[1]))
dictated by consideration for some other C++ compiler. VC7.1 does issue a warning warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data for that code. I would suggest to consider either change type of variable count from int to size_t or disable C4267 for this piece of code for MS compilers. --- Ovanes Markarian <om_boost@keywallet.com> wrote:
On Wed, April 11, 2007 17:51, Oleg V. Zhylin wrote:
Hi,
Is there a reason to use type int in the code at line 487 in oserializer.hpp?
int count = sizeof(t) / ( static_cast<const char *>(static_cast<const void *>(&t[1]))
- static_cast<const char *>(static_cast<const void *>(&t[0]))
C++ standard draft states in section 5.3.3 [expr.sizeof]
The result is a constant of an implementation-defined type which is the same type as that which is named size_t in the standard header <cstddef>(18.1).
I assume otherwise you will get a warning, that a sign can be lost through the assignment. The problem here is that expression (type* - type*) results not in an unsigned type (size_t) but a signed difference type. If you divide unsigned value through a signed value you get a signed value. And then you would (according to your suggestion) assign it to an unsigned value => warning.
With Kind Regards,
Ovanes Markarian
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
WBR Oleg V. Zhylin ovz@yahoo.com ____________________________________________________________________________________ Finding fabulous fares is fun. Let Yahoo! FareChase search your favorite travel sites to find flight and hotel bargains. http://farechase.yahoo.com/promo-generic-14795097

Well, the standart states in [expr.mul] §5.6 section 4: The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined... and later in [expr.add] §5.7 secion 6: When two pointers to elements of the same array object are subtracted, the result is the difference of the subscripts of the two array elements. The type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined as ptrdiff_t in the <cstddef> header (18.1)... In your second example you have no pointer arithmetics (subtraction, which you had in the first example). You have only cast to the pointer type, which is in fact unsigned and the produced warning is correct. Using ptrdiff_t instead of int results in no warning at MSVC 8.0, where ptrdiff_t is defined as: typedef _W64 int ptrdiff_t; Which is signed ;) The following test code in MSVC: ptrdiff_t result = sizeof(int)/(reinterpret_cast<int*>(&arr[0])-reinterpret_cast<int*>(&arr[1])); std::cout << result << '\n'; std::cout << typeid(reinterpret_cast<int*>(&arr[0])-reinterpret_cast<int*>(&arr[1])).name() <<'\n'; std::cout << typeid(sizeof(int)/(reinterpret_cast<int*>(&arr[0])-reinterpret_cast<int*>(&arr[1]))).name() <<'\n'; Produces the output: 0 int unsigned int The first output is implementation defined (size_t/negative number) but you get no warning. With Kind Regards, Ovanes Markarian According to the standart IMO this line is correct. On Thu, April 12, 2007 15:08, Oleg V. Zhylin wrote:
At least for VC7.1 compiler
int a, b;
cout<<typeid(sizeof(a)/(a - b)).name()<<endl;
prints "unsingned int" and issues no warnings about int -> size_t conversion. Thus I still wonder if usage of int type in
int count = sizeof(t) / ( static_cast<const char *>(static_cast<const void
*>(&t[1]))
dictated by consideration for some other C++ compiler. VC7.1 does issue a warning
warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data
for that code. I would suggest to consider either change type of variable count from int to size_t or disable C4267 for this piece of code for MS compilers.
--- Ovanes Markarian <om_boost@keywallet.com> wrote:
On Wed, April 11, 2007 17:51, Oleg V. Zhylin wrote:
Hi,
Is there a reason to use type int in the code at line 487 in oserializer.hpp?
int count = sizeof(t) / ( static_cast<const char *>(static_cast<const void *>(&t[1]))
- static_cast<const char *>(static_cast<const void *>(&t[0]))
C++ standard draft states in section 5.3.3 [expr.sizeof]
The result is a constant of an implementation-defined type which is the same type as that which is named size_t in the standard header <cstddef>(18.1).
I assume otherwise you will get a warning, that a sign can be lost through the assignment. The problem here is that expression (type* - type*) results not in an unsigned type (size_t) but a signed difference type. If you divide unsigned value through a signed value you get a signed value. And then you would (according to your suggestion) assign it to an unsigned value => warning.
With Kind Regards,
Ovanes Markarian
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
WBR Oleg V. Zhylin ovz@yahoo.com
____________________________________________________________________________________ Finding fabulous fares is fun. Let Yahoo! FareChase search your favorite travel sites to find flight and hotel bargains. http://farechase.yahoo.com/promo-generic-14795097 _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Thanks for the detailed response, Ovanes. As C4267 MSVC warning tells us, problem is that size_t could be larger than int, particularly for 64 bit projects, and thus the definition of ptrdiff_t in MSVC header files.
typedef _W64 int ptrdiff_t;
I agree that ptrdiff_t might be a better option as a type of count variable in the expression discussed. --- Ovanes Markarian <om_boost@keywallet.com> wrote:
Well,
the standart states in [expr.mul] §5.6 section 4: The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined...
and later in [expr.add] §5.7 secion 6: When two pointers to elements of the same array object are subtracted, the result is the difference of the subscripts of the two array elements. The type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined as ptrdiff_t in the <cstddef> header (18.1)...
In your second example you have no pointer arithmetics (subtraction, which you had in the first example). You have only cast to the pointer type, which is in fact unsigned and the produced warning is correct.
Using ptrdiff_t instead of int results in no warning at MSVC 8.0, where ptrdiff_t is defined as:
typedef _W64 int ptrdiff_t;
Which is signed ;)
The following test code in MSVC:
ptrdiff_t result =
sizeof(int)/(reinterpret_cast<int*>(&arr[0])-reinterpret_cast<int*>(&arr[1]));
std::cout << result << '\n'; std::cout <<
typeid(reinterpret_cast<int*>(&arr[0])-reinterpret_cast<int*>(&arr[1])).name()
<<'\n'; std::cout <<
typeid(sizeof(int)/(reinterpret_cast<int*>(&arr[0])-reinterpret_cast<int*>(&arr[1]))).name()
<<'\n';
Produces the output: 0 int unsigned int
The first output is implementation defined (size_t/negative number) but you get no warning.
With Kind Regards,
Ovanes Markarian
According to the standart IMO this line is correct.
On Thu, April 12, 2007 15:08, Oleg V. Zhylin wrote:
At least for VC7.1 compiler
int a, b;
cout<<typeid(sizeof(a)/(a - b)).name()<<endl;
prints "unsingned int" and issues no warnings about int -> size_t conversion. Thus I still wonder if usage of int type in
int count = sizeof(t) / ( static_cast<const char *>(static_cast<const void
*>(&t[1]))
dictated by consideration for some other C++ compiler. VC7.1 does issue a warning
warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data
for that code. I would suggest to consider either change type of variable count from int to size_t or disable C4267 for this piece of code for MS compilers.
--- Ovanes Markarian <om_boost@keywallet.com> wrote:
On Wed, April 11, 2007 17:51, Oleg V. Zhylin wrote:
Hi,
Is there a reason to use type int in the code at line 487 in oserializer.hpp?
int count = sizeof(t) / ( static_cast<const char *>(static_cast<const void *>(&t[1]))
- static_cast<const char *>(static_cast<const void *>(&t[0]))
C++ standard draft states in section 5.3.3 [expr.sizeof]
The result is a constant of an implementation-defined type which is the same type as that which is named size_t in the standard header <cstddef>(18.1).
I assume otherwise you will get a warning, that a sign can be lost through the assignment. The problem here is that expression (type* - type*) results not in an unsigned type (size_t) but a signed difference type. If you divide unsigned value through a
signed
value you get a signed value. And then you would (according to your suggestion) assign it to an unsigned value => warning.
With Kind Regards,
Ovanes Markarian
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
WBR Oleg V. Zhylin ovz@yahoo.com
____________________________________________________________________________________
Finding fabulous fares is fun. Let Yahoo! FareChase search your favorite travel sites to find flight and hotel bargains. http://farechase.yahoo.com/promo-generic-14795097 _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
WBR Oleg V. Zhylin ovz@yahoo.com ____________________________________________________________________________________ The fish are biting. Get more visitors on your site using Yahoo! Search Marketing. http://searchmarketing.yahoo.com/arp/sponsoredsearch_v2.php

At 4:10 PM +0200 4/12/07, Ovanes Markarian wrote:
the standart states in [expr.mul] §5.6 section 4: The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined...
Note that C++ follows C89 in this. C99 changed this and defined division to truncate toward zero (following Fortran, according the C99 rationale). Interestingly, the draft C++ update (n2135) retains the original wording and has not been updated to match C99. That's Core Issue 614, so may change before the next C++ revision is finalized.
participants (3)
-
Kim Barrett
-
Oleg V. Zhylin
-
Ovanes Markarian