Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

179
Views
¿Cuándo debo pasar o devolver una estructura por valor?

Una estructura se puede pasar/devolver por valor o pasar/devolver por referencia (a través de un puntero) en C.

El consenso general parece ser que el primero se puede aplicar a estructuras pequeñas sin penalización en la mayoría de los casos. Consulte ¿Hay algún caso en el que devolver una estructura directamente sea una buena práctica? y ¿Hay alguna desventaja en pasar estructuras por valor en C, en lugar de pasar un puntero?

Y que evitar una desreferencia puede ser beneficioso tanto desde el punto de vista de la velocidad como de la claridad. Pero, ¿qué cuenta como pequeño ? Creo que todos podemos estar de acuerdo en que esta es una estructura pequeña:

 struct Point { int x, y; };

Que podemos pasar por valor con relativa impunidad:

 struct Point sum(struct Point a, struct Point b) { return struct Point { .x = ax + bx, .y = ay + by }; }

Y que task_struct de Linux es una estructura grande:

https://github.com/torvalds/linux/blob/b953c0d234bc72e8489d3bf51a276c5c4ec85345/include/linux/sched.h#L1292-1727

Que nos gustaría evitar poner la pila a toda costa (¡especialmente con esas pilas de modo kernel de 8K!). Pero, ¿qué pasa con los medianos? Supongo que las estructuras más pequeñas que un registro están bien. Pero ¿qué pasa con estos?

 typedef struct _mx_node_t mx_node_t; typedef struct _mx_edge_t mx_edge_t; struct _mx_edge_t { char symbol; size_t next; }; struct _mx_node_t { size_t id; mx_edge_t edge[2]; int action; };

¿Cuál es la mejor regla general para determinar si una estructura es lo suficientemente pequeña como para que sea segura pasarla por valor (sin circunstancias atenuantes, como una recursividad profunda)?

Por último, por favor, no me digas que necesito perfilar. Estoy pidiendo una heurística para usar cuando soy demasiado perezoso/no vale la pena investigar más a fondo.

EDITAR: tengo dos preguntas de seguimiento basadas en las respuestas hasta ahora:

  1. ¿Qué pasa si la estructura es en realidad más pequeña que un puntero a ella?

  2. ¿Qué pasa si una copia superficial es el comportamiento deseado (la función llamada realizará una copia superficial de todos modos)?

EDITAR: No estoy seguro de por qué esto se marcó como un posible duplicado, ya que en realidad vinculo la otra pregunta en mi pregunta. Estoy pidiendo una aclaración sobre lo que constituye una pequeña estructura y soy muy consciente de que la mayoría de las veces las estructuras deben pasarse por referencia.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

En arquitecturas integradas pequeñas (8/16 bits), siempre pase por puntero, ya que las estructuras no triviales no encajan en registros tan pequeños, y esas máquinas generalmente también carecen de registros.

En arquitecturas similares a PC (procesadores de 32 y 64 bits), está bien pasar una estructura por valor siempre que sizeof(mystruct_t) <= 2*sizeof(mystruct_t*) y la función no tenga muchas (generalmente más de 3 palabras de máquina). valor de) otros argumentos. En estas circunstancias, un compilador de optimización típico pasará/devolverá la estructura en un registro o par de registros. Sin embargo, en x86-32, este consejo debe tomarse con cautela, debido a la extraordinaria presión de registro con la que debe lidiar un compilador x86-32: pasar un puntero puede ser aún más rápido debido a la reducción del derrame y llenado de registros.

Devolver una estructura por valor en PC, por otro lado, sigue la misma regla, excepto por el hecho de que cuando una estructura se devuelve por puntero, la estructura que se debe completar también se debe pasar por puntero; de lo contrario , la persona que llama y la persona que llama tienen que ponerse de acuerdo sobre cómo administrar la memoria para esa estructura.

over 4 years ago · Santiago Trujillo Report

0

Mi experiencia, casi 40 años de embebido en tiempo real, los últimos 20 usando C; es que la mejor manera es pasar un puntero.

En cualquier caso, se debe cargar la dirección de la estructura, luego se debe calcular el desplazamiento para el campo de interés...

Al pasar toda la estructura, si no se pasa por referencia, entonces

  1. no se coloca en la pila
  2. se copia, generalmente mediante una llamada oculta a memcpy()
  3. se copia en una sección de la memoria que ahora está 'reservada' y no está disponible para ninguna otra parte del programa.

Existen consideraciones similares para cuando una estructura se devuelve por valor.

Sin embargo, las estructuras "pequeñas", que se pueden mantener completamente en un registro de trabajo para dos, se pasan en esos registros, especialmente si se usan ciertos niveles de optimización en la declaración de compilación.

Los detalles de lo que se considera "pequeño" dependen del compilador y de la arquitectura de hardware subyacente.

over 4 years ago · Santiago Trujillo Report

0

Dado que la parte de paso de argumento de la pregunta ya está respondida, me centraré en la parte de retorno.

En mi opinión, lo mejor que puede hacer es no devolver estructuras o punteros a estructuras, sino pasar un puntero a la 'estructura de resultado' a la función.

 void sum(struct Point* result, struct Point* a, struct Point* b);

Esto tiene las siguientes ventajas:

  • La estructura de result puede vivir en la pila o en el montón, a discreción de la persona que llama.
  • No hay problemas de propiedad, ya que está claro que la persona que llama es responsable de asignar y liberar la estructura de resultados.
  • La estructura podría incluso ser más larga de lo que se necesita, o estar incrustada en una estructura más grande.
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!