In case of integer overflows what is the result of (unsigned int) * (int)? unsigned or int?

To answer your question: the type of an expression multiplying an int and an unsigned int will be an unsigned int in C/C.

To answer your question: the type of an expression multiplying an int and an unsigned int will be an unsigned int in C/C++. To answer your implied question, one decent way to deal with possible overflow in integer arithmetic is to use the "IntSafe" set of routines from Microsoft: blogs.msdn.com/michael_howard/archive/20... It's available in the SDK and contains inline implementations so you can study what they're doing if you're on another platform.

Ensure that w * h doesn't overflow by limiting w and h.

Rather, use if (!h || w > 4096/h) return NULL;. – R.. Sep 18 '10 at 1:35.

Do the w*h calculation in long long, check if bigger than MAX_UINT EDIT : alternative : if overflown (w*h)/h! = w (is this always the case?! Should be, right?

).

That would fail if h is 0 – Spudd86 May 28 '10 at 14:46 Bad advice. Try if (!h || w > 4096/h) return NULL;. – R.. Sep 18 '10 at 1:36.

The type of w*i is unsigned in your case. If I read the standard correctly, the rule is that the operands are converted to the larger type (with its signedness), or unsigned type corresponding to the signed type (which is unsigned int in your case). However, even if it's unsigned, it doesn't prevent the wraparound (writing to memory before buf), because it might be the case (on i386 platform, it is), that p-1 is the same as p-1u.

Anyway, in your case, both buf-1 and bufbig unsigned number would be undefined behavior, so the signed/unsigned question is not that important. Note that signed/unsigned matters in other contexts - eg. (int)(x*y/2) gives different results depending on the types of x and y, even in the absence of undefined behaviour. I would solve your problem by checking for overflow on line 9; since 4096 is a pretty small constant and 4096*4096 doesn't overflow on most architectures (you need to check), I'd do if (w>4096 || h>4096 || w*h > 4096) return (NULL); This leaves out the case when w or h are 0, you might want to check for it if needed.

In general, you could check for overflow like this: if(w*h > 4096 || (w*h)/w! =h || (w*h)%w! =0).

In C/C++ the pn notation is really a shortcut to writting *(p+n), and this pointer arithmetic takes into account the sign. So p-1 is valid and refers to the value immediately before *p. So the sign really matters here, the result of arithmetic operator with integer follow a set of rules defined by the standard, and this is called integer promotions.

Check out this page: INT02-C. Understand integer conversion rules.

2 changes make it safer: if (w >= 4096 || h >= 4096 || w*h > 4096) return NULL; ... unsigned i; Note also that it's not less a bad idea to write to or read from past the buffer end. So the question is not whether i*w may become negative, but whether 0 For example, it doesn't make a difference whether this is (unsigned)0x80000000 or (int)0x80000000, the program will seg-fault anyway.

For C, refer to "Usual arithmetic conversions" (C99: Section 6.3.1.8, ANSI C K&R A6.5) for details on how the operands of the mathematical operators are treated. In your example the following rules apply: C99: Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type. Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.

ANSI C: Otherwise, if either operand is unsigned int, the other is converted to unsigned int.

Then the problem goes away. In any case, i*w is guaranteed to be.

W*h may overflow to be less than 4096, though – rampion Apr 6 '09 at 15:16 Wrong, the code did not ensure than i*w will be.

W*h could overflow if w and/or h are sufficiently large and the following validation could pass. 9. If (w*h > 4096) 10.

Return (NULL); On int , unsigned int mixed operations, int is elevated to unsigned int, in which case, a negative value of 'i' would become a large positive value. In that case &bufi*w would be accessing a out of bound value.

Unsigned arithmetic is done as modular (or wrap-around), so the product of two large unsigned ints can easily be less than 4096. The multiplication of int and unsigned int will result in an unsigned int (see section 4.5 of the C++ standard). Therefore, given large w and a suitable value of h, you can indeed get into trouble.

Making sure integer arithmetic doesn't overflow is difficult. One easy way is to convert to floating-point and doing a floating-point multiplication, and seeing if the result is at all reasonable. As qwerty suggested, long long would be usable, if available on your implementation.(It's a common extension in C90 and C++, does exist in C99, and will be in C++0x.).

– yinyueyouge Apr 6 '09 at 15:29 I got it from webstore.ansi.org - search for C++ standard. It costs $30. ANSI and other standardization organizations typically finance themselves by charging for copies of their standards.

– David Thornley Apr 6 '09 at 15:56 Ridiculous advice - convert to floating point?!? Try if (!h || w > 4096/h) return NULL;. – R.. Sep 18 '10 at 1:38.

There are 3 paragraphs in the current C1X draft on calculating (UNSIGNED TYPE1) X (SIGNED TYPE2) in 6.3.1.8 Usual arithmetic coversions, N1494, WG 14: C - Project status and milestones Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type. Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type. Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.So if a is unsigned int and be is int, parsing of (a * b) should generate code (a * (unsigned int)b).

Will overflow if be UINT_MAX. If a is unsigned int and be is long of greater size, (a * b) should generate ((long)a * (long)b). Will overflow if a * be > LONG_MAX or a * be On your second question about the type expected by "indexer", the answer appears "integer type" which allows for any (signed) integer index.

6.5.2.1 Array subscripting Constraints 1 One of the expressions shall have type ‘‘pointer to complete object type’’, the other expression shall have integer type, and the result has type ‘‘type’’. Semantics 2 A postfix expression followed by an expression in square brackets is a subscripted designation of an element of an array object. The definition of the subscript operator is that E1E2 is identical to (*((E1)+(E2))).

Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1E2 designates the E2-th element of E1 (counting from zero). It is up to the compiler to perform static analysis and warn the developer about possibility of buffer overrun when the pointer expression is an array variable and the index may be negative. Same goes about warning on possible array size overruns even when the index is positive or unsigned.

To actually answer your question, without specifying the hardware you're running on, you don't know, and in code intended to be portable, you shouldn't depend on any particular behavior.

1 Unsigned arithmetic is defined in C and C++. Given the maximum unsigned int value (which is available in a header somewhere), you can predict what happens precisely. – David Thornley Apr 6 '09 at 15:22.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions