看起来很容易找到这样的Java工具(Checkstyle,JCSC),但我似乎找不到一个用于C/C++的工具.我不是在寻找类似于lint的静态代码分析器,我只想检查编码标准,如变量命名,大小写,间距,标识,括号放置等.
当我在Lua中执行"os.execute"时,控制台会快速弹出,执行命令,然后关闭.但是有没有办法只使用标准的Lua库来取回控制台输出?
我使用静态全局变量构造函数作为方便注册函数的技巧,这个想法是这样的:
typedef int (*FuncPtr)(int);
struct RegHelper
{
RegHelper(const char * Name, FuncPtr Func)
{
Register(Name, Func);
}
}
#define REGISTER(func) RegHelper gRegHelper_ ## func (#func, func);
Run Code Online (Sandbox Code Playgroud)
现在我可以这样注册函数(我用它来实现某种反射):
int Foo(int a)
{
return a * 123;
}
REGISTER(Foo)
int Bar(int a)
{
return a * 456;
}
REGISTER(Bar)
Run Code Online (Sandbox Code Playgroud)
问题是,如果我在静态库中使用它,有时链接器会检测到编译单元没有被使用,并且它会丢弃整个内容.所以全局变量没有构造,函数没有注册......
我的问题是:我可以做些什么来解决这个问题?在初始化期间调用每个编译单元中的虚函数似乎触发了全局变量的构造,但这并不觉得非常安全.还有其他建议吗?
在阅读Herb Sutter博客上的这篇文章后,我进行了一些实验,遇到了令我困惑的事情.我正在使用Visual C++ 2005,但如果这依赖于实现,我会感到惊讶.
这是我的代码:
#include <iostream>
using namespace std;
struct Base {
//Base() {}
~Base() { cout << "~Base()" << endl; }
};
int main()
{
const Base & f = Base();
}
Run Code Online (Sandbox Code Playgroud)
运行时,它会显示两次 " ~Base()" 但是如果我取消对构造函数的注释,它只会显示一次!
有没有人对此有解释?
我在Visual C++ 2008上尝试了这个代码,它显示A和B没有相同的地址.
int main()
{
{
int A;
printf("%p\n", &A);
}
int B;
printf("%p\n", &B);
}
Run Code Online (Sandbox Code Playgroud)
但是当B被定义时A不再存在,在我看来,相同的堆栈位置可以重用...
我不明白为什么编译器看起来不像一个非常简单的优化(例如在较大的变量和递归函数的上下文中可能很重要).并且似乎重用它不会在CPU和内存上更重.有没有人对此有解释?
我想答案是"因为它比它看起来要复杂得多",但老实说我不知道.
编辑:关于以下答案和评论的一些准确性.
这段代码的问题在于,每次调用此函数时,堆栈都会"增加一个整数".当然,这在示例中没有问题,但考虑大变量和递归调用,并且您可以轻松避免堆栈溢出.
我建议的是内存优化,但我不知道它会如何损害性能.
顺便说一句,这种情况发生在发布版本中,将进行所有优化.
如果启用了增量链接,Visual C++会在$(TargetDir)中生成*.ilk文件,我可以覆盖此行为并将其重定向到另一个目录吗?(不使用构建后步骤)
我想通过向它发送大量随机击键来强调测试win32应用程序,我想知道是否有人能指出我可以使用的一些软件.理想情况下,我应该能够指定可以发送哪些击键,以及控制速率(随机最小/最大).
在Lua中,使用不带l值的=运算符似乎等同于print(r值),这里有一些在Lua独立解释器中运行的示例:
> = a
nil
> a = 8
> = a
8
> = 'hello'
hello
> = print
function: 003657C8
Run Code Online (Sandbox Code Playgroud)
等等...
我的问题是:在哪里可以找到=运算符的这种用法的详细描述?它是如何工作的?是否意味着特殊的默认l值?我想问题的根源在于我不知道在Google中输入什么内容以查找有关它的信息:-)
编辑:
谢谢你的答案,你是对的,这是翻译的一个特点.愚蠢的问题,因为我不知道哪个理由让我完全忽略了这一点.我应该避免在早晨咖啡之前发布:-)为了完整起见,这里是解释器中处理这个问题的代码:
while ((status = loadline(L)) != -1) {
if (status == 0) status = docall(L, 0, 0);
report(L, status);
if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
l_message(progname, lua_pushfstring(L,
"error calling " LUA_QL("print") " (%s)",
lua_tostring(L, …Run Code Online (Sandbox Code Playgroud) 例如,如果我声明一个长变量,我可以假设它将始终在"sizeof(long)"边界上对齐吗?Microsoft Visual C++在线帮助是这样说的,但它是标准行为吗?
更多信息:
一个.可以明确地创建一个未对齐的整数(*bar):
char foo [5]
int*bar =(int*)(&foo [1]);
湾 显然,#pragma pack()只影响结构,类和联合.
C.MSVC文档声明POD类型与它们各自的大小对齐(但它总是或默认情况下,它是标准行为,我不知道)
以下是我编写的一些代码来说明我的问题:
struct Foo
{
Foo() {}
Foo( Foo && );
Foo( const Foo & ) = delete;
};
Foo GetFoo()
{
return Foo();
}
int main()
{
Foo f = GetFoo();
}
Run Code Online (Sandbox Code Playgroud)
删除的复制构造函数会阻止隐式默认移动构造函数,因此我必须明确声明一个.但我既没有使用"= default"也没有为它提供实现,但整个事情正在编译和链接.如果我删除声明,它将不再编译.
我发现链接器并没有抱怨丢失的移动构造函数,这真的很令人惊讶.你能帮我理解为什么吗?
c++ ×6
c ×2
lua ×2
visual-c++ ×2
coding-style ×1
constructor ×1
linker ×1
optimization ×1
reference ×1
stack ×1
temporary ×1
testing ×1
windows ×1