是否允许标准 C assert(e) 宏多次计算 e? C++11 或更高版本呢?我在 the Open Group spec 中看不到任何保证,并且通过一些搜索( 1 、 2 ),答案对我来说并不明显。
上下文:在 assert(func() != NULL) 中可以多次调用 func() 吗?
是的,出于其他原因我已经知道这是个坏主意:如the glibc manual指出,如果定义了 NDEBUG,则根本不会评估 assert() 的参数。但是,假设NDEBUG 未 定义,最大 次e 是否有任何保证?
this one 提示的问题.
最佳答案
在 C11 标准 (ISO/IEC 9899:2011) 中,§7.1.4 库函数的使用说:
Each of the following statements applies unless explicitly stated otherwise in the detailed descriptions that follow: …
Any invocation of a library function that is implemented as a macro shall expand to code that evaluates each of its arguments exactly once, fully protected by parentheses where necessary, so it is generally safe to use arbitrary expressions as arguments.186) Likewise, those function-like macros described in the following subclauses may be invoked in an expression anywhere a function with a compatible return type could be called.187)
186) Such macros might not contain the sequence points that the corresponding function calls do.
187) Because external identifiers and some macro names beginning with an underscore are reserved, implementations may provide special semantics for such names. For example, the identifier
_BUILTIN_abscould be used to indicate generation of in-line code for theabsfunction. Thus, the appropriate header could specify#define abs(x) _BUILTIN_abs(x)for a compiler whose code generator will accept it. In this manner, a user desiring to guarantee that a given library function such as
abswill be a genuine function may write#undef abswhether the implementation’s header provides a macro implementation of
absor a built-in implementation. The prototype for the function, which precedes and is hidden by any macro definition, is thereby revealed also.
§7.2 中的序言 诊断 <assert.h> 说:
The
assertmacro shall be implemented as a macro, not as an actual function. If the macro definition is suppressed in order to access an actual function, the behavior is undefined.
和§7.2.1.1 assert宏 说:
The
assertmacro puts diagnostic tests into programs; it expands to a void expression. When it is executed, ifexpression(which shall have a scalar type) is false (that is, compares equal to 0), theassertmacro writes information about the particular call that failed (including the text of the argument, the name of the source file, the source line number, and the name of the enclosing function — the latter are respectively the values of the preprocessing macros__FILE__and__LINE__and of the identifier__func__) on the standard error stream in an implementation-defined format.191) It then calls theabortfunction.191) The message written might be of the form:
Assertion failed:expression, functionabc, filexyz, linennn.
标准的措辞就这么多了——这在实践中是如何转化的?
很大程度上取决于对语句的解释:
如果assert被视为通过宏实现的函数,那么它的参数只被计算一次(转换为字符串是一个编译时操作,不计算表达式)。
如果assert被视为“不是函数”(因为它明确地是一个宏),那么引用的限制不一定适用于它。
在实践中,我确定意图是 assert 的表达式参数应该只评估一次(并且只有在上次包含 NDEBUG header 时未定义 <assert.h> 时才会评估)——所以我认为它受到约束,就好像它是通过宏实现的函数一样。我还会考虑任何实现 assert 的实现以这样一种方式,表达式被评估为有缺陷的两次。我不确定引用的 Material 是否支持这一点,但这是我在标准中所知道的所有相关 Material 。
关于c++ - 符合标准的 C assert() 可以多次评估其参数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39664672/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby数组,我们在StackOverflow上找到一
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)