c语言结构体变量直接赋值或者结构体指针变量解引用后赋值
·
最近,我在看linux的内核源码,遇到了如下代码:
int pty_resize(struct tty_struct *tty, struct winsize *ws)
{
struct pid *pgrp, *rpgrp;
unsigned long flags;
struct tty_struct *pty = tty->link;
/* For a PTY we need to lock the tty side */
mutex_lock(&tty->termios_mutex);
if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
goto done;
/* Get the PID values and reference them so we can
avoid holding the tty ctrl lock while sending signals.
We need to lock these individually however. */
spin_lock_irqsave(&tty->ctrl_lock, flags);
pgrp = get_pid(tty->pgrp);
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
spin_lock_irqsave(&pty->ctrl_lock, flags);
rpgrp = get_pid(pty->pgrp);
spin_unlock_irqrestore(&pty->ctrl_lock, flags);
if (pgrp)
kill_pgrp(pgrp, SIGWINCH, 1);
if (rpgrp != pgrp && rpgrp)
kill_pgrp(rpgrp, SIGWINCH, 1);
put_pid(pgrp); /**put:释放的意思 */
put_pid(rpgrp);
tty->winsize = *ws; /**直接使用了函数指针变量解引用方式实现的,并且直接使用了复制运算符进行结构体整体赋值 */
pty->winsize = *ws; /* Never used so will go away soon */
done:
mutex_unlock(&tty->termios_mutex);
return 0;
}
其中又有ws这个结构体指针变量使用解引用运算符“*”完成解引用后,将整个结构体内存中的数值直接赋值给tty指向的winsize结构体变量。
这就遇到一个问题,C语言标准是从什么时候开始支持结构体变量参与赋值运算符的,因为我们知道赋值运算符“=”往往只支持32-bit架构的4字节变量赋值运算,结构体变量往往内部数据特别多,直接使用赋值运算符“=”给其他结构体变量赋值会不会有问题。
答:从C89标准开始结构体变量直接参与赋值运算就已经支持了,当让结构体指针变量解引用后参与赋值运算也是一样支持的。C89标准发布比较早,也就是从最初结构体变量直接参与赋值运算就已经定下来了,而不是后面的C99或者其他更高标准才支持的。因此,在编程过程中可以大胆的使用结构体直接赋值操作,有时候直接赋值更容易理解。
问题二:结构体变量直接赋值会不会影响效率?
答:完全不会,结构体变量参与赋值运算在底层上是一次按位拷贝(浅拷贝),有点等效于函数memcpy()实现数据复制,运行时将源结构体占用的整个内存数据,原封不动地赋值到目标结构体占用的内存空间中。
便在编译器(GCC、clang、MSVC等)在开启优化选项(例如-O2)后,对结构体直接赋值的优化已经非常成熟了,底层本质上等效与memcpy()函数,都编译生成对应的汇编代码以及机器码。
因此,完全不用考虑结构体复制造成的开销问题。
更多推荐


所有评论(0)