问题标签 [gcc-extensions]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - GCC - 修改函数返回后继续执行的位置
有可能在 GCC 中做这样的事情吗?
- 这可以使用 C 和 GCC 扩展以可移植的方式实现,而不使用特定于平台的程序集吗?
- 堆栈状态不会在正常返回点和更改后的返回点之间改变,那么是否可以重用从常规返回中恢复堆栈和寄存器状态的代码?
- 考虑到函数可能被内联也可能不被内联,如果调用它必须改变返回地址,如果内联它只能改变代码路径而不是当前函数返回地址,因为这会破坏代码
- 备用返回点不需要是标签,但我希望GCC的标签扩展地址可以在这种情况下派上用场
只是为了澄清意图 - 它是关于错误处理的。这个例子是一个最小的例子,只是为了说明事情。我打算在更深层次的环境中使用它,以在发生错误时停止执行。我还假设状态没有改变,我可能错了,因为在两个返回点之间没有添加额外的局部变量,所以我希望编译器生成的代码在 foo 的返回时可以被重用为此并节省使用longjmp
、设置和传递跳转缓冲区的开销。
该示例“确实有意义”,因为它的目的是展示我想要实现的目标,而不是展示它为什么以及如何在实际代码中有意义。
为什么您的想法比简单地从 foo() 返回一个值并让 bar() 有条件地返回或执行某处Else: 更简单更好?
它并不简单,而且您的建议在实践中并不适用,仅在一个简单示例的背景下,但它更好,因为:
1 - 它不涉及额外返回值
2 - 它不涉及对值的额外检查
3 - 它不涉及额外的跳跃
我可能错误地假设目标在这一点上应该是明确的,并且在所有的澄清和解释之后。这个想法是在没有任何额外开销的情况下从深度调用链中提供“转义代码路径”。通过重用编译器生成的代码来恢复前一个调用帧的状态,并简单地修改函数返回后恢复执行的指令。成功跳过“转义码路径”,出现的第一个错误进入它。
至于 Basile Starynkevitch 提出longjmp
的“高效”和“即使 10 亿个 longjmp 仍然合理”的说法——sizeof(jmp_buf)
给了我 156 个字节,这显然是保存几乎所有寄存器和一堆其他东西所需的空间,所以以后可以恢复。这些是很多操作,并且这样做十亿次远远超出了我个人对“高效”和“合理”的理解。我的意思是 10 亿个跳转缓冲区本身就超过 145 GB的内存,然后还有 CPU 时间开销。没有很多系统甚至可以负担得起那种“合理的”。
c++ - 将 __builtin_expect 降级为内联函数是否安全?
我正在研究一些定义的 C++ 代码
我想知道 - 为什么不是内联函数?即为什么不
(或者可能
因为 x 应该是某些条件检查的结果)
宏和函数应该做的基本一样吧?但后来我想知道:也许是因为__builtin_expect
......当它在内联辅助函数中时,它的工作方式会有所不同吗?
c++ - C/C++ 中括号内的代码块是否合法,MSCL 可以编译吗?
我有以下代码:
(如果你好奇我为什么会写出那样恶心的代码。答案是我不会。我正在编写一个输出 C 代码的生成器,拥有这样的语句会让事情变得容易得多。)
该代码在 Apple LLVM 版本 7.0.2 上编译和工作(当然会警告未使用的代码),但在 MSCL 10.0 和 14.0 上失败(错误 C2059:语法错误:'{')。
我的问题是:1)这种代码(-abuse)有名称吗?2) 在任何 C/C++ 标准中是否合法?3) 有没有办法让 MSCL 接受它?
c - 如何返回每个函数实例大小不同的 VLA?
我正在使用一个不错的 GCC 扩展,它允许我们在结构中声明 VLA。现在我找到了一种通过这种方式将 VLA 传递给函数(按值)的方法。我还找到了一种返回方法,但在非常有限的情况下。
这个例子的功能代码是这样的:
上面的例子是为测试目的而设计的(特别是为了比较它编译的二进制代码)。
然而,这是非常有限的,因为返回数组的大小在函数的不同调用之间没有变化。
我怎样才能使返回的数组大小等于函数参数之一或此函数中的某个其他局部参数。
我认为alloca
在这种情况下对我没有帮助,因为它分配的内存在函数退出(IRC)处立即被销毁。
我想写这样的东西:
换句话说,问号内的类型可能是什么?或者也许还有其他解决方案(但不使用malloc
)?
这种函数的理论用法理论上需要另一种类型来存储返回值,因为调用者无法获得返回结构的大小(除非有办法避免这种情况?)。但乍一看它应该是这样的:
如果我们这样做:
它不起作用,因为 VM 返回类型func5
将取决于它的参数或局部变量。然而,目前这一切都是理论上的,因为我们仍然无法定义这个函数。
c++ - 什么是__attribute__ vector_size?
鉴于此代码:
如何为 MSVC 2015 重写?
c - 属性(noinline)支持需要什么 ARM 编译器版本?
我不确定如何找出要支持的任何给定属性需要哪个版本的 ARM 编译器(armcc)。
例如__atribute__((noinline))
?
见 http://www.keil.com/support/man/docs/armcc/armcc_chr1359124975804.htm
c++ - 函数返回类型说明符c ++ type中的变量声明
我正在尝试 codefights.com 并注意到有人回答了一个问题,该问题涉及在向量中给出所有最长的字符串:
他在函数的返回类型说明符中声明了一个变量,谁能告诉我为什么允许这样做?我没有在我的机器上编译,也找不到执行此操作的 gcc 扩展,在此先感谢:)。
c - 我们可以混合使用 __extension__ 和 -std=c99 吗?
该标准不允许在指向函数的指针void *
和指向函数的指针之间进行转换:
6.3.2.3:8 指向一种类型函数的指针可以转换为指向另一种类型函数的指针,然后再转换回来;结果应与原始指针比较。如果转换后的指针用于调用类型与指向的类型不兼容的函数,则行为未定义。
glib/gtk 中有几个函数打破了这个规则,一个例子是g_signal_handlers_block_by_func
在 a 中转换为大写的典型示例GtkEntry
:
gpointer
是一个typedef
forvoid *
并g_signal_handlers_unblock_by_func
使用gpointer
:
因此,使用编译此代码-std=c99
会给出以下警告:
我能找到使编译器静音的唯一方法是使用__extension__
:
抱歉这么长的序言,但正如您所见,glib / gtk 正在使用 gcc 扩展,并且无法在-pedantic
模式下(没有警告)编译gtk
使用信号处理程序的程序。
我的问题是:
我们可以-std=c99
结合使用__extension__
还是被迫使用-std=gnu99
?
换句话说,是否__extension__
暗示(强制)使用扩展进行编译,或者只是一条使编译器静音的指令,并且我的程序正在未定义的行为下工作?
c - 使用 gcc/clang C 扩展来测试宏参数是否为指针
使用 gcc/tcc/clang 对 C 语言 (C11) 的扩展,是否可以检测宏参数是否具有指针类型?
详细信息:我正在使用一个应该采用单个间接指针的宏,但很容易将指针传递给该指针,因为这是相应的“构造函数”宏所采用的,但这样做会出错,所以我目前正在使用类似的东西:
保护自己免受自己的伤害。有没有更好的实施方式ISPTR()
?
c++ - GNU order-statistics-tree 的意外结果
我刚刚了解了一些关于 GNU 基于策略的数据结构的知识。但是我在这个问题上得到了一些意想不到的结果:(原版是中文描述的,所以我已经翻译了。)
您需要编写一个支持以下操作的数据结构:
- 插入号码
x
- 删除号码
x
- 查找 number
x
的 order("order" 是指小于这个 number 的元素个数+1) - 查找订单号
x
- 查找 number
x
的前缀 - 查找 number
x
的后缀
但只有 55% 的数据点被接受。而在错误答案点中,问题出现在数百行之后。所以这一定是一个很小的问题。你能弄清楚吗?我将不胜感激。
我对意外结果的了解是它们通常大于预期结果。7
但在程序输出时需要一点6
。所以我真的很困惑。我什至不知道case
问题发生在哪个剂量。
此外,保证数据点是正确的。我自己写Treap
的检查过了。
编辑
数据范围:
操作限制:100000 次数字限制:每个数字都在 [-10000000,10000000]