Is the maximum size_t value (SIZE_MAX) defined relative to other integer types?

I am writing a library of functions that will safely convert between different numeric types or die. My intention is about equal parts of create-useful-library and learn-C-edge-cases.

My function int-to- size_ttriggers a GCC warning -Wtype-limits, which states that I should not test if intmore than SIZE_MAXbecause it will never be true. (Another function that converts intto ssize_tproduces an identical warning about SSIZE_MAX.)

My MCVE with additional comments and steps for kids:

#include <stdint.h>  /* SIZE_MAX */
#include <stdlib.h>  /* exit EXIT_FAILURE size_t */

extern size_t i2st(int value) {
    if (value < 0) {
        exit(EXIT_FAILURE);
    }
    // Safe to cast --- not too small.
    unsigned int const u_value = (unsigned int) value;
    if (u_value > SIZE_MAX) {  /* Line 10 */
        exit(EXIT_FAILURE);
    }
    // Safe to cast --- not too big.
    return (size_t) u_value;
}

Compiler warnings

I get similar warnings from GCC 4.4.5 on Linux 2.6.34:

$ gcc -std=c99 -pedantic -Wall -Wextra -c -o math_utils.o math_utils.c

math_utils.c: In function ‘i2st’:
math_utils.c:10: warning: comparison is always false due to limited range of data type

... as well as from GCC 4.8.5 on Linux 3.10.0:

math_utils.c: In function ‘i2st’:
math_utils.c:10:5: warning: comparison is always false due to limited range of data type [-Wtype-limits]
     if (u_value > SIZE_MAX) {  /* Line 10 */
     ^

, , . ( , " " .)

C

C 1999 , int , SIZE_MAX.

"6.5.3.4 sizeof" size_t , ", <stddef.h> ( )".

"7.17 <stddef.h>" size_t " sizeof". (, !)

"7.18.3 " --- " size_t" :

SIZE_MAX 65535

... SIZE_MAX 65535. int ( ) , .

" unsigned int vs. size_t" , ( ):

size_t , , a unsigned int, .

" 7.17" C, .

Open Group " 64- ", "64- " ( ):

ISO/IEC 9899: 1990, - C (ISO C) short int, int, long int pointer [...] , int short s, long int s, size_t , . [...] :

sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)= sizeof(size_t)

, int SIZE_MAX ... , , . " 7" sys/types.h docs .

, size_t , int, C, some_unsigned_int > SIZE_MAX ? , ?

-

- , , size_t, / .

+4
3

C , size_t int, , - . size_t , ; 24 , size_t 24- , , int.

GCC . . , , . ( , GCC.) , , , , , , , .


OP , , . 3.3.2 ( 2003 ), -, -W. 12963 , , , , , . , GCC ( ) , . ( .) -Wall. -W -Wextra, (-Wtype-limits) -Wextra. .


.

-Wall, GCC, . " , , ( ), ". , GCC :

, -Wall. , , ; , , . -Wextra, .

. , , GCC " " & "||". (, "*" "+", .) , , GCC .

. , , -Wall, , . , , ; , ( ) .

, , , , GCC , - , , , . , , -Wextra . . , , , , , . -Wtypes-limit .

+7

, size_t , int. , SIZE_MAX <= INT_MAX, , , GCC .

, #if:

#if INT_MAX > SIZE_MAX
if (u_value > SIZE_MAX) {  /* Line 10 */
    exit(EXIT_FAILURE);
}
#endif
+4

I agree with Remo.D interpretation .

size_tis indicated as a standard unsigned integer, but the standard does not limit its size in relation to any of them, except as it says that it should be able to hold at least 65535.

It can be smaller, equal or larger in size than unsigned int.

+1
source

Source: https://habr.com/ru/post/1686705/


All Articles