usan sistema que operativo epoc32 empresa dispositivos definicion celulares antiguo c++ symbian

c++ - que - sistema operativo de nokia antiguo



¿Cuál es el propósito y el tipo de devolución del operador__builtin_offsetof? (4)

Es un built-in proporcionado por el compilador de GCC para implementar el offsetof macro que se especifica en el estándar C y C ++:

GCC - offsetof

Devuelve el desplazamiento en bytes en el que se encuentra un miembro de una estructura / unión POD.

Muestra:

struct abc1 { int a, b, c; }; union abc2 { int a, b, c; }; struct abc3 { abc3() { } int a, b, c; }; // non-POD union abc4 { abc4() { } int a, b, c; }; // non-POD assert(offsetof(abc1, a) == 0); // always, because there''s no padding before a. assert(offsetof(abc1, b) == 4); // here, on my system assert(offsetof(abc2, a) == offsetof(abc2, b)); // (members overlap) assert(offsetof(abc3, c) == 8); // undefined behavior. GCC outputs warnings assert(offsetof(abc4, a) == 0); // undefined behavior. GCC outputs warnings

@Jonathan proporciona un buen ejemplo de dónde puede usarlo. Recuerdo haberlo utilizado para implementar listas intrusivas (listas cuyos elementos de datos incluyen los punteros siguiente y anterior), pero no recuerdo dónde fue útil implementarlo, lamentablemente.

¿Cuál es el propósito del operador __builtin_offsetof (o el operador _FOFF en Symbian) en C ++?

Además, ¿qué devuelve? ¿Puntero? Número de bytes?


El propósito de un operador __offsetof incorporado es que el proveedor del compilador pueda continuar definiendo una macro offsetof (), pero que funcione con las clases que definen el operador unario &. La definición de macro típica de offsetof () solo funcionaba cuando (& lvalue) devolvía la dirección de ese valor r. Es decir

#define offsetof(type, member) (int)(&((type *)0)->member) // C definition, not C++ struct CFoo { struct Evil { int operator&() { return 42; } }; Evil foo; }; ptrdiff_t t = offsetof(CFoo, foo); // Would call Evil::operator& and return 42


Como @litb señala y @JesperE muestra, offsetof () proporciona un desplazamiento entero en bytes (como un valor de size_t ).

¿Cuándo podrías usarlo?

Un caso en el que podría ser relevante es una operación basada en tablas para leer una enorme cantidad de parámetros de configuración diversos de un archivo y rellenar los valores en una estructura de datos igualmente enorme. Reducir lo enorme a lo SO trivial (e ignorar una amplia variedad de prácticas necesarias en el mundo real, como definir tipos de estructuras en los encabezados), quiero decir que algunos parámetros podrían ser enteros y otras cadenas, y el código podría verse débilmente como:

#include <stddef.h> typedef stuct config_info config_info; struct config_info { int parameter1; int parameter2; int parameter3; char *string1; char *string2; char *string3; int parameter4; } main_configuration; typedef struct config_desc config_desc; static const struct config_desc { char *name; enum paramtype { PT_INT, PT_STR } type; size_t offset; int min_val; int max_val; int max_len; } desc_configuration[] = { { "GIZMOTRON_RATING", PT_INT, offsetof(config_info, parameter1), 0, 100, 0 }, { "NECROSIS_FACTOR", PT_INT, offsetof(config_info, parameter2), -20, +20, 0 }, { "GILLYWEED_LEAVES", PT_INT, offsetof(config_info, parameter3), 1, 3, 0 }, { "INFLATION_FACTOR", PT_INT, offsetof(config_info, parameter4), 1000, 10000, 0 }, { "EXTRA_CONFIG", PT_STR, offsetof(config_info, string1), 0, 0, 64 }, { "USER_NAME", PT_STR, offsetof(config_info, string2), 0, 0, 16 }, { "GIZMOTRON_LABEL", PT_STR, offsetof(config_info, string3), 0, 0, 32 }, };

Ahora puede escribir una función general que lea líneas del archivo de configuración, descartando comentarios y líneas en blanco. A continuación, aísla el nombre del parámetro, y lo busca en la tabla desc_configuration (que puede ordenar para que pueda hacer una búsqueda binaria - varias preguntas SO lo hacen). Cuando encuentra el registro config_desc correcto, puede pasar el valor que encontró y la entrada config_desc a una de dos rutinas: una para procesar cadenas, la otra para procesar enteros.

La parte clave de esas funciones es:

static int validate_set_int_config(const config_desc *desc, char *value) { int *data = (int *)((char *)&main_configuration + desc->offset); ... *data = atoi(value); ... } static int validate_set_str_config(const config_desc *desc, char *value) { char **data = (char **)((char *)&main_configuration + desc->offset); ... *data = strdup(value); ... }

Esto evita tener que escribir una función separada para cada miembro separado de la estructura.


Como @litb, dijo: el desplazamiento en bytes de un miembro struct / class. En C ++ hay casos en los que no está definido, en caso de que el compilador se queje. IIRC, una forma de implementarlo (en C, al menos) es hacer

#define offsetof(type, member) (int)(&((type *)0)->member)

Pero estoy seguro de que hay problemas, pero dejaré eso al lector interesado para señalar ...