tipos funciones datos bool c++ gcc type-conversion implicit-conversion

funciones - Advertencias o errores para la conversión implícita de primitivas en C++



funciones en c++ (6)

En el lenguaje de programación C ++, tercera edición , apéndice C.6, llamado "Conversión de tipo implícita", Bjarne Stroustrup clasifica las conversiones como promociones y conversiones : los primeros "conservan los valores" (ese es su caso 2), los segundos no. (caso 1).

Acerca de las conversiones , dice que "los tipos fundamentales se pueden convertir unos en otros de una manera desconcertante. En mi opinión, se permiten demasiadas conversiones". y "Un compilador puede advertir sobre muchas conversiones cuestionables. Afortunadamente, muchos compiladores sí lo hacen".

Las promociones en el otro lado son seguras, y parece que un compilador no debe dar una advertencia por ellas.

Las advertencias del compilador generalmente no son obligatorias. Por lo general, en los borradores de C ++ y en los documentos ANSI finales , se informa que "los implementadores deben emitir una advertencia" donde se sugiere: puede verificarlo usted mismo para obtener más información si es necesario.

EDITADO: añadido C ++ 11 nota:

En el lenguaje de programación The C ++, 4ª edición , el apéndice de la 3ª edición se informó y se extendió a la sección 10.5, "Conversión de tipo implícita" nuevamente.

Como las consideraciones anteriores son las mismas, C ++ 11 define con mayor precisión las "conversiones de reducción" y agrega la notación inicializadora {} (6.3.5), con la cual los truncamientos conducen a un error de compilación.

He hecho un poco de refactorización de algunos códigos C ++ y descubrí numerosos errores que surgen de conversiones implícitas de las que no tengo conocimiento.

Ejemplo

struct A *a(); bool b() { return a(); } void c() { int64_t const d(b()); }

Cuestiones

  1. En b , el tipo de retorno de a se convierte silenciosamente a bool .
  2. En c , el valor devuelto desde b se promueve silenciosamente a int64_t .

Pregunta

¿Cómo puedo recibir advertencias o errores para la conversión implícita entre tipos primitivos ?

Nota

  1. El uso de -Wconversion parece recoger solo varias conversiones arbitrarias no relacionadas con el ejemplo anterior.
  2. BOOST_STRONG_TYPEDEF no es una opción (mis tipos deben ser POD, ya que se usan en estructuras de disco).
  3. C también es de interés, sin embargo, este problema se refiere a una base de código C ++.


Microsoft Visual C ++ daría una advertencia sobre la conversión de reducción de A* a bool .

Ver el Compilador de Advertencia C4800

Por otro lado, la promoción no es una conversión "peligrosa", porque es imposible perder datos.

EDITAR: Demostración

C:/Users/Ben>copy con test.cpp bool f( void ) { return new int(); } ^Z 1 file(s) copied. C:/Users/Ben>cl /c /W4 test.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. test.cpp test.cpp(1) : warning C4800: ''int *'' : forcing value to bool ''true'' or ''false'' ( performance warning)


Puede usar una de las herramientas de análisis estático disponibles, programas como clint o equivalentes de C ++, o una de las herramientas disponibles comercialmente. Muchas de estas herramientas pueden detectar conversiones implícitas problemáticas.


Según tengo entendido, no puede controlar la conversión implícita entre tipos primitivos: es obligatorio por el estándar y cualquier compilador compatible solo lo ejecutará en silencio.

¿Estás seguro de que un enfoque como BOOST_STRONG_TYPEDEF no funcionará en tu problema? Una clase sin funciones de miembro virtual y solo un miembro de datos primitivos es básicamente nada más que un tipo de datos POD. Simplemente puede seguir el mismo enfoque y solo permitir la conversión al tipo primitivo básico; ejemplo:

#include <iostream> #include <stdexcept> struct controlled_int { // allow creation from int controlled_int(int x) : value_(x) { }; controlled_int& operator=(int x) { value_ = x; return *this; }; // disallow assignment from bool; you might want to use BOOST_STATIC_ASSERT instead controlled_int& operator=(bool b) { throw std::logic_error("Invalid assignment of bool to controlled_int"); return *this; }; // creation from bool shouldn''t happen silently explicit controlled_int(bool b) : value_(b) { }; // conversion to int is allowed operator int() { return value_; }; // conversion to bool errors out; you might want to use BOOST_STATIC_ASSERT instead operator bool() { throw std::logic_error("Invalid conversion of controlled_int to bool"); }; private: int value_; }; int main() { controlled_int a(42); // This errors out: // bool b = a; // This gives an error as well: //a = true; std::cout << "Size of controlled_int: " << sizeof(a) << std::endl; std::cout << "Size of int: " << sizeof(int) << std::endl; return 0; }