【问题标题】:Reinitialize timeval struct重新初始化 timeval 结构
【发布时间】:2011-09-21 16:04:42
【问题描述】:

如何从 time.h 重新初始化 timeval 结构?

我知道我可以将结构的两个成员都重置为零,但是我忽略了其他一些方法吗?

【问题讨论】:

  • 重新初始化为什么?如何在初始化满意后复制它,然后将其复制回原件以重置它?

标签: c++ struct timeval


【解决方案1】:

对任意(可能是聚合)类型进行零初始化的完全正确且可移植(尽管是 C99)的方法:

myTime = (struct timeval){0};

这甚至适用于包含指针和浮点成员的结构,即使实现不使用全零位作为空指针和浮点零的表示。

【讨论】:

  • 你领先我两分钟 :-)。顺便说一句,我认为通常使用空大括号会更好,因为即使结构的第一个元素是另一个结构,它们也可以工作。
  • 空大括号根本不起作用;它们是无效的 C。它们是有效的,但是在 C++ 中。请注意,{0} 总是 在 C 中有效,即使第一个元素是另一个结构(或者即使根本不涉及结构或联合)。
  • 我会买空大括号不是标准的;我站得更正了。但是,如果结构的第一个元素是另一个结构,“gcc std=c99 -pedantic -Wall”会说“警告:初始化器周围缺少大括号”。它需要 myStruct = (struct mystruct){ { 0 } }。这是一个毫无意义的警告吗?
  • @Nemo:我认为这是一个毫无意义且令人恼火的警告。我可能会看到它对于超过 {0} 的初始化程序很有用,但 GCC 不应该警告那种习惯于“我希望这个结构零初始化”的特定形式。
  • @R。 @Michael,是的,这个警告真的很烦人。我通常会关闭那个特定的。我什至认为,总的来说,这种警告确实具有误导性。该标准有一个明确的段落说明这种“扁平化”初始化程序是如何工作的。这是语言(设计师)想要的功能。该警告仅具有只有少数人使用初始化程序的效果。这只会适得其反。
【解决方案2】:

memset 可能碰巧在您的平台上工作,但它实际上不是推荐的(便携式)方法......

这是:

struct timeval myTime;

myTime = (struct timeval){ 0 };

memset 之所以有效,是因为struct timeval 的所有元素恰好都具有零值,这些值由您平台上的全零位模式表示。

但这不是规范要求的。特别是,POSIX 不要求 time_t 类型为整数,C 也不要求浮点零表示为全零字节。

使用初始化语法保证结构的字段将被正确设置为零,无论它们是整数、浮点、指针还是其他结构......即使这些东西的表示在内存中不是全零.一般情况下,memset 并非如此。

【讨论】:

  • R:我的立场是正确的。 (我猜我已经习惯了 GCC 扩展......)已修复。
【解决方案3】:

假设您希望将 struct timeval 结构重新初始化为零值,无论它们是浮点类型还是整数类型,也不管浮点类型的零表示形式如何,这种方法适用于 C90 或更高版本或 C++ :

static struct timeval init_timeval;  // or whatever you want to call it

// ...

myTime = init_timeval;

R.'s answerNemo's answer 一样,这也将处理NULL 指针,无论它们如何表示。我无法想象为什么struct timeval 会有一个指针,但我提到这一点是因为该技术对struct timeval 以外的结构很有用。

与其他答案相比,它的缺点是它需要在某处定义静态或全局变量。优点是它可以与非 C99 编译器一起使用。

【讨论】:

  • 如果你要这样做,至少添加const 以避免浪费bss/data。此外,如果您编写const struct timeval init_timeval = {0};(注意我删除了static),编译器可能足够聪明,可以消除生成任何代码以实际创建自动对象并只生成memset-等效代码当你写my_timeval = init_timeval;...
【解决方案4】:

如果您正在寻找单线,我想您也可以使用 memset 来完成这项工作:

struct timeval myTime;

/* snip ... myTime is now initialized to something */

memset(&myTime, 0, sizeof(timeval)); // Reinitialized to zero

【讨论】:

  • 不要因为不涉及 OOP 而将问题从 c++ 重新标记到 c。现在,所有答案实际上都不适用于 OP 的 C++ 代码。
【解决方案5】:

您可以使用memset,然后您还可以将任何特定于平台的成员归零。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 2012-07-16
    相关资源
    最近更新 更多