我正在调试GDB中的一些C++代码,我发现有些调用正在使用所谓的"合成指针".谷歌搜索没有产生任何有意义的结果.在这里搜索SO,其标题中"合成"的大多数问题都是指一些Java特性(即使他们建议我"合成",在这种情况下,可能意味着"由编译器人工生成的东西").
例如,看一下这个回溯,从一个操作中获取,在构造函数中执行MyClass
,超过一个被调用的类成员m
(此代码已经编译-O2
):
#0 MyClass (arg=..., this=<synthetic pointer>) at somefile.h:144
144 m->lock();
gdb$ print this
$1 = (MyClass * const) <synthetic pointer>
gdb$ print *this
$2 = <optimized out>
Run Code Online (Sandbox Code Playgroud)
上面的堆栈跟踪清楚地表明这this
是一个指向已经优化的对象的指针,但是如何在其上调用方法(即其构造函数)?我的猜测是,即使m
在代码中主动使用了封闭的object(),一些优化也让编译器决定封闭的object(this
)不是必需的.由于m->lock()
无法优化的方法调用必须在某处发出,编译器会创建一个"假的"(合成的?)对象,它位于内存中,只是为了换行m
.
我没有强大的编译器经验,所以我不知道这个结论是否真的有意义.有人可以对此有所了解吗?
谢谢.
我有一个C++类,它是日志系统的前端.它的日志记录功能是使用C++ 11的可变参数模板实现的:
template <typename... Args>
void Frontend::log(const char *fmt, Args&&... args) {
backend->true_log(fmt, std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
每个日志记录后端都实现自己的版本true_log
,除其他外,它使用转发的参数进行调用vsnprintf
.例如:
void Backend::true_log(const char *fmt, ...) {
// other stuff..
va_list ap;
va_start(ap, fmt);
vsnprintf(buffer, buffer_length, fmt, ap);
va_end(ap);
// other stuff..
}
Run Code Online (Sandbox Code Playgroud)
一切都很好,我很高兴.
现在,我想对log()
参数添加静态检查:具体来说,我想使用GCC的printf格式属性.
我开始使用标记log()
函数__attribute__ ((format (printf, 2, 3)))
(因为this
第一个"隐藏"参数,我需要将参数索引移动一个).这不起作用,因为如果失败并出现编译错误:
error: args to be formatted is not ‘...’
Run Code Online (Sandbox Code Playgroud)
然后,我尝试将相同的属性添加到该true_log()
函数中.它编译,但实际上没有执行错误检查:我试图传递log()
一些无效的格式/变量组合,并且没有发出警告.也许这种检查"太晚了",换句话说,有关变量的信息已经在调用链中丢失了?
作为最后的手段,如果我注释log()
有__attribute__ ((format (printf, 2, 0)))
,我会收到关于错误的格式字符串警告,但无诊断会为无效的格式/变量组合发出.
总结问题: …
我有这个处理图像的项目.我用来执行大多数实际图像处理的库需要在Android设备或模拟器上运行这些测试.我想提供一些它应该处理的测试图像,问题是我不知道如何在androidTest APK中包含这些文件.我可以通过上下文/资源提供图像,但我宁愿不污染我的项目资源.有关如何在仪表化单元测试中提供和使用文件的任何建议?
请考虑以下代码:
class Foo {
Foo() {}
};
class Bar {
Foo &Foo_ref;
Bar() : Foo_ref() {}
};
Run Code Online (Sandbox Code Playgroud)
按原样编写,我收到错误:
tmp.cc: In constructor Bar::Bar(): tmp.cc:7: error: value-initialization of Foo& Bar::Foo_ref, which has reference type
我试过了我能想到的每一个变化.我究竟做错了什么?如何将引用成员初始化为新实例?我现在使用const指针而不是引用作为解决方法,但我更喜欢使用引用.
我有一个简单的问题,我已经坚持了一段时间,我找不到答案.基本上,我正在创建一个对象并尝试访问变量而不使用静态变量,因为我被告知这是错误的方法.以下是该问题的一些示例代码.我在第一个类中收到一个无法解析为变量的错误.我希望能够做的是访问t.name
main之外的其他方法,也可以访问其他类.为了解决这个问题,我会Test2.name
在Test2
课堂上使用并将变量设为静态,如果我错了就纠正我,但我认为这是错误的做法.任何帮助将不胜感激=)
public class Test {
public static void main(String[] args) {
Test2 t = new Test2("Joe");
}
public void displayName() {
System.out.println("Name2: " + t.name);
}
}
public class Test2 {
String name;
public Test2 (String nm) {
name = nm;
}
}
Run Code Online (Sandbox Code Playgroud) 在我的服务器类的主要方法中,我有一系列关于if
聊天程序的保留关键字的语句,我正在尝试使用变量的值和.equalsIgnoreCase
方法来遍历.问题是即使我的变量保持一定的值,在执行程序时,else
即使变量和其中一个if
条件之间存在完全匹配,代码也会一直进入子句.代码编译得很好,但我无法弄清楚为什么会发生这种情况.我在开始if
语句之前打印了变量的值,以验证它是否保持正确的值.我的代码中的snipet如下所示:
System.out.println("Keyword is : " + keyword);
if (keyword.equalsIgnoreCase("who"))
{
System.out.println("calling who function");
whoFunction(address, socket, port);
}
else if (keyword.equalsIgnoreCase("whoami"))
{
whoami(address, socket, port, clientAddress);
}
else if (keyword.equalsIgnoreCase("all"))
{
all(message);
}
else if (keyword.equalsIgnoreCase("Bye"))
{
bye(address, socket, port, clientAddress);
}
else
{
newUser(keyword, address, searchListLength, clientAddress, port);
}
Run Code Online (Sandbox Code Playgroud)
无论关键字的值是什么,它总是选择最终的else语句.如你所见,这将导致我总是打电话给我的newUser
班级.我在这里错过了什么吗?可能会盯着我的脸:/