最好传递struct或指向struct的指针?

最好传递struct或指向struct的指针?,c,struct,embedded,C,Struct,Embedded,我有一个数据结构,它将在函数中读取 我想要尽可能最小的内存、代码大小和速度。我在做AVR typedef struct { uint16_t clu; uint16_t num; uint32_t cur_rel; } FSAVEPOS; 现在,一个将文件位置存储到结构中的函数: // Approach 1 FSAVEPOS save_pos(const FFILE* file); // return value // Approach 2 void save_pos

我有一个数据结构,它将在函数中读取

我想要尽可能最小的内存、代码大小和速度。我在做AVR

typedef struct {
    uint16_t clu;
    uint16_t num;
    uint32_t cur_rel;
} FSAVEPOS;
现在,一个将文件位置存储到结构中的函数:

// Approach 1
FSAVEPOS save_pos(const FFILE* file); // return value

// Approach 2
void save_pos(const FFILE* file, FSAVEPOS* pos); // modify reference
以及一个反转此的函数(FFILE对象已修改):


您认为最好的方法是什么?

在第一种情况下,当您在C中返回一个结构时,如果它符合或通过引用隐式传递并修改AFAIK,它通常会在寄存器中返回。因此,在最好的情况下,它比第二种方法更好,在最坏的情况下,它与第二种方法相等

在第二种情况下,它取决于指针的大小和结构的大小。在这种情况下,没有测量就很难说出任何事情。不过,对于这样大小的结构,可能不会有太大的不同


但是,您应该考虑与API的其余部分保持一致性,如果您不能操作(如果操作失败),有一个系统来通知错误。

< P>第一种情况下,当您返回C中的结构时,通常登记在寄存器中,如果它适合或隐式地通过引用和修改AFAIK传递。因此,在最好的情况下,它比第二种方法更好,在最坏的情况下,它与第二种方法相等

在第二种情况下,它取决于指针的大小和结构的大小。在这种情况下,没有测量就很难说出任何事情。不过,对于这样大小的结构,可能不会有太大的不同


但是,您应该考虑与API的其余部分保持一致性,如果您不能操作(如果操作失败),有一个系统来通知错误。

< P>第一种情况下,当您返回C中的结构时,通常登记在寄存器中,如果它适合或隐式地通过引用和修改AFAIK传递。因此,在最好的情况下,它比第二种方法更好,在最坏的情况下,它与第二种方法相等

在第二种情况下,它取决于指针的大小和结构的大小。在这种情况下,没有测量就很难说出任何事情。不过,对于这样大小的结构,可能不会有太大的不同


但是,您应该考虑与API的其余部分保持一致性,如果您不能操作(如果操作失败),有一个系统来通知错误。

< P>第一种情况下,当您返回C中的结构时,通常登记在寄存器中,如果它适合或隐式地通过引用和修改AFAIK传递。因此,在最好的情况下,它比第二种方法更好,在最坏的情况下,它与第二种方法相等

在第二种情况下,它取决于指针的大小和结构的大小。在这种情况下,没有测量就很难说出任何事情。不过,对于这样大小的结构,可能不会有太大的不同


但是,您应该考虑与API的其余部分保持一致性,并且如果您不能操作(如果操作失败),有一个通知错误的系统。

< P>如果您试图最小化内存占用,那么使用指针来更好地传递一个比指针大得多的<代码>结构> <代码>类型。显著较小的数据最好按值传递。如果指针和数据的大小大致相同,则无关紧要

假设您在AVR32上,指针将为32位,结构为64位(加上任何填充)

这表明您最好通过指针/引用进行传递。然而,结构不是特别大,其他考虑因素可能占主导地位-对于您的
struct
类型,它实际上没有太多,因为它不是特别大。您需要测量相关数量(内存使用量、代码大小、速度等)以确保

因此,我建议最好的办法是测量——这些因素受主机体系结构、编译器设置、编译器实现质量等的影响

尽管您没有询问,但较大的类型(如
uint32\u t
)往往比较小的类型(如
uint16\u t
)具有更大的对齐要求。这样做的结果是一个相当常见的指导原则,即对结构的成员进行排序,以便更大的类型首先出现在内存中。这在您的情况下可能也不重要(16位类型将与16位边界对齐,32位类型与32位边界对齐,这是一个公平的赌注,因此在您的情况下可能没有填充)。但是,如果您有三个
uint16\u t
成员而不是两个,那么您最好先订购
uint32\u t
成员。换句话说,不是

typedef struct
{
    uint16_t a,b,c;
    uint32_t d;
} SOME_TYPE;
你最好换一个顺序

typedef struct
{
    uint32_t d;
    uint16_t a,b,c;
} SOME_TYPE;

如果您试图最小化内存占用,那么最好使用指针传递比指针大得多的
struct
类型。显著较小的数据最好按值传递。如果指针和数据的大小大致相同,则无关紧要

假设您在AVR32上,指针将为32位,结构为64位(加上任何填充)

这表明您最好通过指针/引用进行传递。然而,结构不是特别大,其他考虑因素可能占主导地位-对于您的
struct
类型,它实际上没有太多,因为它不是特别大。您需要测量相关数量(内存使用量、代码大小、速度等)以确保

因此,我建议最好的办法是测量——这些因素受主机体系结构、编译器设置、编译器实现质量等的影响

尽管您没有询问,但较大的类型(如
uint32\u t
)往往比较小的类型(如
uint16\u t
)具有更大的对齐要求。由此产生的一个结果是,订购您的stru成员是一个相当常见的指南
typedef struct
{
    uint32_t d;
    uint16_t a,b,c;
} SOME_TYPE;