GNU/Linux >> Tutoriales Linux >  >> Linux

Prevención del desbordamiento de enteros C

En C, el archivo de encabezado que desea es <stdint.h> y la constante es UINT32_MAX

static void update_value(char op)
{
    if (op == '+')
        if ( value < (UINT32_MAX - 1))
            value++;    // uint32_t global value
        else
            printf("too big!\n");
    else
       if (value > 0)
           value--;
       else
           printf("too small!\n");
}

Para C++, puede usar cualquier cantidad de soluciones que se encuentran aquí:¿Cuál es el equivalente en C++ de UINT32_MAX?


Descubrí que la solución más general es verificar si el valor incrementado es mayor que el valor anterior, o si el valor disminuido es menor que el valor anterior. Esto funciona solo si el valor no está firmado , independientemente del tamaño de la variable, y es prácticamente tan portátil como el código C.

static void update_value(char op)
{
  if (op == '+') {
    if (value + 1 > value) value ++;
  } else {
    if (value - 1 < value) value --;
  }
}

Tenga en cuenta que el código puede funcionar con valores firmados , pero según el estándar C, este sería un comportamiento indefinido, y los compiladores son libres de reemplazar if (value + 1 > value) ... con if (1) ... . No deberías no use este código con valores firmados a menos que tenga un proceso implementado para auditar el código de objeto generado después de que se haya vinculado .

Con gcc y clang, deberás agregar -fwrapv opción para dejar que este código funcione para valores firmados; con otros compiladores, su kilometraje puede variar.

Una forma sensata de hacer esto es ser específico del tipo y usar constantes de limits.h . Por ejemplo:

#include "limits.h"

static void update_int(char op, int *value)
{
  int val = *value; // ignoring NULL pointer dereference

  if (op == '+') {
    if (val != INT_MAX) *value = val + 1;
  } else {
    if (val != INT_MIN) *value = val - 1;
  }
}

static void update_int(char op, unsigned int *value)
{
  unsigned int val = *value; // ignoring NULL pointer dereference

  if (op == '+') {
    if (val != UINT_MAX) *value = val + 1;
  } else {
    if (val != UINT_MIN) *value = val - 1;
  }
}

Tal vez estés buscando <limits> :http://www.cplusplus.com/reference/limits/numeric_limits/

Puedes hacer algo como esto para obtener lo que quieres:

unsigned int n = numeric_limits<unsigned int>::max()

También tienes este <cstdint> :http://www.cplusplus.com/reference/cstdint/

UINTN_MAX:Valor máximo del tipo sin firmar de ancho exacto (Exactamente 2^N-1)


Linux
  1. Evitar que un script bash se ejecute simultáneamente

  2. ¿Cómo agrego usuarios a otro grupo de usuarios?

  3. Valor de retorno de la función de tiempo de espera

  4. ¿Qué es una resolución de jiffie en Linux Kernel?

  5. ¿Cómo se calcula la prioridad del proceso?

So-notify:un notificador de preguntas de desbordamiento de pila

os.MkDir y os.MkDirAll valor de permiso?

usando awk con condiciones de valor de columna

¿Cómo usar kill SIGUSR2 en bash?

Reparación de codificación de etiquetas ID3

Tiempo de espera de caché arp predeterminado