编译 Ruby 内联 C 代码 - 解决错误
我正在尝试让这个 Ruby 内联 C 代码 http://pastie.org/2825882 工作。该代码可以在普通 C 中运行,但在这里我收到错误和警告。导致此错误的原因是什么?
./backtrack_inline.rb:67: error: lvalue required as unary '&' operand
另外,为什么我会收到以下错误?
./backtrack_inline.rb:73: error: too few arguments to function 'backtrack'
检查生成的 C 代码 (http://pastie.org/2826036) 我没有发现参数有任何问题。但我也收到以下警告:
./backtrack_inline.rb:73: warning: passing argument 1 of 'backtrack' makes integer from pointer without a cast
./backtrack_inline.rb:73: warning: passing argument 2 of 'backtrack' makes integer from pointer without a cast
./backtrack_inline.rb:73: warning: passing argument 3 of 'backtrack' makes integer from pointer without a cast
I am trying to get this Ruby inline C code http://pastie.org/2825882 to work. The code works in vanilla C, but here I get errors and warnings. What causes this error?
./backtrack_inline.rb:67: error: lvalue required as unary '&' operand
Also, why do I get the following error?
./backtrack_inline.rb:73: error: too few arguments to function 'backtrack'
Inspecting the resulting C code ( http://pastie.org/2826036) I fail to see anything wrong with the arguments. But I do also get the following warnings:
./backtrack_inline.rb:73: warning: passing argument 1 of 'backtrack' makes integer from pointer without a cast
./backtrack_inline.rb:73: warning: passing argument 2 of 'backtrack' makes integer from pointer without a cast
./backtrack_inline.rb:73: warning: passing argument 3 of 'backtrack' makes integer from pointer without a cast
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从这里开始:
如果你查看生成的代码,
backtrack
函数是在第 29 行定义的:它有七个参数,原来的六个,加上
VALUE self
因为它有已转换为Scan
类上的方法。第 67 行对此函数的调用如下所示:
它只有六个参数。 RubyInline 不会将其转换为对对象方法的调用,它只是逐字复制它。这也是有关
makes integer frompointer without a cast
的警告的来源:函数定义已转换为采用VALUE
,但您正在使用原始函数调用类型。错误消息表明错误来自
backtrack_inline.rb
中的第 73 行,因为生成代码的第 54 行上的指令:它基本上告诉编译器“重置”其行和文件值以防止错误,并将下一行 (55) 视为文件
./backtrack_inline.rb
中的第 61 行。实际行是 67, 12 领先于 55,但编译器将其报告为 73, 12 领先于 61(重置为的值)并且来自不同的文件。这种技术在这种情况下并不起作用,因为它没有考虑 RubyInline 添加的额外行。源代码中的实际行是 69。解决此问题的一个简单方法是将 backtrack 函数的定义更改为 C 函数,而不是将其添加为对象上的方法。将
builder.c
更改为builder.prefix
(位于 Ruby 文件的第 38 行)。如果您希望在 Ruby 中将backtrack
作为对象的方法使用,那么这将不起作用。如果是这种情况,您可能需要创建另一个函数作为方法,然后包装“真正的”回溯函数。接下来,查看
This 实际上指的是生成代码的第 61 行,它看起来像:
StringValuePtr
是一个 宏定义为:这是
左值中的
来自。您需要添加一个局部变量作为左值:&
需要作为一元的地方'&'操作数在我的例子中(Mac OS X Snow Leopard、Ruby 1.9.3-p0、RubyInline 3.11.0)这两个更改使脚本运行没有错误,但给出了警告
:实际上指的是ruby文件的第46行:
s
和ss
是char *
,即64位指针(在此machine),函数的返回类型为int
- 32位。添加显式转换修复了这个问题:它现在可以干净地运行:(
我希望 14 是正确的答案!)
这是一个 版本包含这些更改的脚本。
Starting with this:
If you look at your generated code, the
backtrack
function is defined on line 29:It has seven arguments, the original six, plus
VALUE self
as it has been converted into a method on theScan
class.The call to this function, on line 67 looks like this:
It has only six arguments. RubyInline doesn't convert this to a call to a method on the object, it simply copies it verbatim. This is also where the warnings about
makes integer from pointer without a cast
come from: the function definition has been converted to takeVALUE
s, but you're calling with the original types.The error message says that the error is from line 73 in
backtrack_inline.rb
because of the directive on line 54 of the generated code:which basically tells the compiler to "reset" its line and file values for errors, and treat the next line (55) as being line 61 in the file
./backtrack_inline.rb
. The actual line is 67, 12 ahead of 55, but the compiler reports it as being 73, 12 ahead of 61 (the value it was reset to) and from a differnt file. This technique doesn't really work in this case as it doesn't take into account the extra lines added by RubyInline. The actual line in the source is 69.A simple fix for this is to change the definition of the
backtrack
function to be just a C function rather than add it as a method on the object. Changebuilder.c
tobuilder.prefix
(on line 38 of your Ruby file). This won't work if you want to havebacktrack
available as a method on the object in Ruby. If that's the case you might need create another function to be the method, which then wraps the "real" backtrack function.Next, looking at
This actually refers to line 61 of the generated code, which looks like:
StringValuePtr
is a macro which is defined as:This is where the
&
inlvalue required as unary '&' operand
comes from. You need to add a local variable to be the lvalue:In my case (Mac OS X Snow Leopard, Ruby 1.9.3-p0, RubyInline 3.11.0) these two changes made the script run without errors, but gave the warning:
This actually refers to line 46 of the ruby file:
s
andss
arechar *
, i.e. 64 bit pointers (on this machine), and the return type of the function isint
- 32 bits. Adding an explicit cast fixed this:It now runs cleanly:
(I hope 14 is the correct answer!)
Here's a version of the script with these changes.
好的,这个问题也在 Ruby 论坛上得到了回答:
http://www.ruby-forum.com/主题/2959614
OK, the question was also answered at Ruby Forum:
http://www.ruby-forum.com/topic/2959614
好吧……再想一下这个问题。
你正在调用一个变量结束。虽然这不是 C 中的保留字 - 并且 ruby 不应该查看它......也许 ruby 感到困惑?
我建议您尝试重命名它以防万一。即使只是排除它也值得尝试。
Ok... thought a bit more about this.
you are calling a variable end. While this isn't a reserved word in C - and ruby shouldn't be looking at it... perhaps ruby is getting confused?
I'd suggest you have a go at renaming it just in case. Worthwhile trying even just to rule it out.