valor sirve que para metodo español dev definir declarar constantes como calificador c++ gcc const function-attributes

c++ - sirve - metodo const java



atributos de función pure/const en diferentes compiladores (2)

En primer lugar, es útil tener en cuenta que "const" es una versión más estricta de "puro", por lo que "puro" se puede utilizar como alternativa si un compilador no implementa "const".

Como han mencionado otros, MSVC realmente no tiene nada similar, pero muchos compiladores han adoptado la sintaxis de GCC, incluidos muchos que no definen __GNUC__ (y algunos que a veces lo hacen y otras veces no, según las banderas).

  • GCC es compatible con pure since 2.96+ y const desde 2.5.0, en caso de que desee verificar la versión.
  • Clang es compatible con ambos; puede usar __has_attribute(pure) y __has_attribute(const) para detectarlas, pero probablemente sea mejor simplemente confiar en la configuración __GNUC__ . Esto también incluye compiladores basados ​​en clang como emscripten y XL C / C ++ 13+.
  • El compilador Intel C / C ++ admite ambos, pero su documentación es terrible, así que no tengo idea de cuándo se agregaron. 16.0+ es ciertamente seguro.
  • Oracle Developer Studio 12.2+ compatible con ambos.
  • ARM C / C ++ Compiler 4.1+ (y posiblemente más antiguo) es compatible con pure y const
  • IBM XL C / C ++ desde al menos 10.1 .
  • TI 8.0+
  • TI 7.3+ con --gcc (detectado con __TI_GNU_ATTRIBUTE_SUPPORT__ ) admite ambos.
  • PGI no lo documenta (AFAICT), pero ambos atributos funcionan (o al menos se ignoran silenciosamente). 17.10+ es seguro, aunque probablemente hayan sido aceptados por mucho más tiempo.

De estos, clang siempre define __GNUC__ y amigos (actualmente a 4.2, IIRC). Intel define __GNUC__ por defecto (aunque se puede suprimir con -no-gcc) como lo hace PGI en modo C ++ (pero no en modo C). Los demás lo tendrás que verificar manualmente.

Oracle Developer Studio también ha sido compatible con pragmas ya que era conocido como Forte Developer 6 . Se usan de forma un poco diferente ya que requieren que especifique el nombre de la función:

/* pure: */ #pragma does_not_write_global_data (funcname) /* const; SPARC-only until 12.2 */ #pragma no_side_effect (funcname)

TI 6.0+ (al menos) admite un #pragma FUNC_IS_PURE; pragma en modo C ++ solamente. En el modo C, es #pragma FUNC_IS_PURE(funcname); .

La mayor parte de esto puede ocultarse detrás de una macro, que es lo que hice en Hedley :

#if / HEDLEY_GNUC_HAS_ATTRIBUTE(pure,2,96,0) || / HEDLEY_INTEL_VERSION_CHECK(16,0,0) || / HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || / HEDLEY_ARM_VERSION_CHECK(4,1,0) || / HEDLEY_IBM_VERSION_CHECK(10,1,0) || / HEDLEY_TI_VERSION_CHECK(8,0,0) || / (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || / HEDLEY_PGI_VERSION_CHECK(17,10,0) # define HEDLEY_PURE __attribute__((__pure__)) #elif HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus) # define HEDLEY_NO_RETURN _Pragma("FUNC_IS_PURE;") #else # define HEDLEY_PURE #endif #if HEDLEY_GNUC_HAS_ATTRIBUTE(const, 2, 5, 0) || / HEDLEY_INTEL_VERSION_CHECK(16,0,0) || / HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || / HEDLEY_ARM_VERSION_CHECK(4,1,0) || / HEDLEY_IBM_VERSION_CHECK(10,1,0) || / HEDLEY_TI_VERSION_CHECK(8,0,0) || / (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || / HEDLEY_PGI_VERSION_CHECK(17,10,0) # define HEDLEY_CONST __attribute__((__const__)) #else # define HEDLEY_CONST HEDLEY_PURE #endif

Esto no incluye las variantes que requerirían los nombres de las funciones como argumento, pero aún cubre la gran mayoría de los usuarios, y es seguro usarlos en todas partes.

Si no desea usar Hedley (es un único dominio público / encabezado CC0), no debería ser demasiado difícil reemplazar las macros de la versión interna. Si eliges hacer eso, probablemente deberías basar tu puerto en el repositorio de Hedley en lugar de esta respuesta ya que es más probable que lo mantenga actualizado.

pure es un atributo de función que dice que una función no modifica ninguna memoria global.
const es un atributo de función que dice que una función no lee / modifica ninguna memoria global.

Dada esa información, el compilador puede hacer algunas optimizaciones adicionales.

Ejemplo para GCC:

float sigmoid(float x) __attribute__ ((const)); float calculate(float x, unsigned int C) { float sum = 0; for(unsigned int i = 0; i < C; ++i) sum += sigmoid(x); return sum; } float sigmoid(float x) { return 1.0f / (1.0f - exp(-x)); }

En ese ejemplo, el compilador podría optimizar la función calcular para:

float calculate(float x, unsigned int C) { float sum = 0; float temp = C ? sigmoid(x) : 0.0f; for(unsigned int i = 0; i < C; ++i) sum += temp; return sum; }

O si su compilador es lo suficientemente inteligente (y no tan estricto sobre los flotadores):

float calculate(float x, unsigned int C) { return C ? sigmoid(x) * C : 0.0f; }

¿Cómo puedo marcar una función de tal manera para los diferentes compiladores, es decir, GCC, Clang, ICC, MSVC u otros?