您使用什么工具在大型Java项目中查找未使用/死代码?我们的产品已经开发了几年,手动检测不再使用的代码变得非常困难.但是,我们尝试尽可能多地删除未使用的代码.
还赞赏对一般战略/技术(特定工具除外)的建议.
编辑:请注意,我们已经使用了代码覆盖率工具(Clover,IntelliJ),但这些都没有多大帮助.死代码仍然有单元测试,并显示为覆盖.我想一个理想的工具可以识别出具有很少其他代码的代码簇,从而允许docues手动检查.
我继承了一个大量使用模板元编程的项目,现在正处于从Visual Studio 2010升级到2012的过程中.一些模板代码在2012年不再有效.我已经提炼了一个最小的例子:
template <typename T, int i>
class MyClass
{
private:
typedef typename T::Nested<i> Found;
};
Run Code Online (Sandbox Code Playgroud)
给出此错误消息:
source.cpp(5): error C2059: syntax error : '<'
source.cpp(6) : see reference to class template instantiation 'MyClass<T,i>' being compiled
source.cpp(5): error C2238: unexpected token(s) preceding ';'
Run Code Online (Sandbox Code Playgroud)
进一步下来MyClass,我可以使用T::Nested<i>,这只是typedef不起作用.
此示例在2010年编译,但不在2012年编译.此代码有什么问题?
我试图弄清楚以下是否是未定义的行为.我觉得这不是UB,但我对标准的阅读使它看起来像是UB:
#include <iostream>
struct A {
A() { std::cout << "1"; }
~A() { std::cout << "2"; }
};
int main() {
A a;
new (&a) A;
}
Run Code Online (Sandbox Code Playgroud)
引用C++ 11标准:
basic.life4说"程序可以通过重用对象占用的存储来结束任何对象的生命周期"
所以之后new (&a) A,原始A对象已经结束了它的生命周期.
class.dtor11.3表示"当创建对象的块退出时,将为具有自动存储持续时间([basic.stc.auto])的构造对象隐式调用析构函数([stmt.dcl])"
因此,退出A时会隐式调用原始对象的析构函数main.
class.dtor15说"如果为生命周期结束的对象([basic.life])调用析构函数,则行为是不确定的."
所以这是未定义的行为,因为原始A不再存在(即使新的a现在存在于同一存储中).
问题是是否A调用了原始的析构函数,或者是否调用了当前命名a的对象的析构函数.
我知道basic.life7,它表示名称a是指放置后的新对象new.但是class.dtor11.3明确地说它是对象的析构函数,它退出被调用的作用域,而不是从作用域的名称引用的对象的析构函数.
我误读了标准,还是这个实际上是未定义的行为?
编辑:有几个人告诉我不要这样做.为了澄清,我绝对不打算在生产代码中这样做!这是针对CppQuiz问题,这是关于 …
c++ placement-new object-lifetime undefined-behavior language-lawyer
在temp.deduct.partial#8中,有一个示例:
template<class... Args> void f(Args... args); // #1
template<class T1, class... Args> void f(T1 a1, Args... args); // #2
template<class T1, class T2> void f(T1 a1, T2 a2); // #3
f(); // calls #1
f(1, 2, 3); // calls #2
f(1, 2); // calls #3; non-variadic template #3 is more specialized
// than the variadic templates #1 and #2
Run Code Online (Sandbox Code Playgroud)
调用#1很简单,因为只有一个可行的专业化。
对于呼叫#2,f?和f?是可行的。我们合成f?(X)和f?(X, Y)。然后,我们同时进行两种类型的推导。
首先f?(X, Y)反对f?(Args... args),推论Args …
我在C#中创建了一个小型测试应用程序,用于设置DateTime.Now和启动StopWatch.每十秒我打印_stopwatch.Elapsed.TotalMilliseconds和(DateTime.Now - _startTime).TotalMilliseconds.
虽然我不认为这两者是完全相同的,但我惊讶地看到它们每20秒线性地发散约1毫秒.我假设DateTime.Now调用系统时钟,而StopWatch做某种积累?
样本输出:
StopWatch : 0,2 DateTime : 1,0 Diff : 0,81
StopWatch : 10000,5 DateTime : 10002,6 Diff : 2,04
(...)
StopWatch : 2231807,5 DateTime : 2231947,7 Diff : 140,13
StopWatch : 2241809,5 DateTime : 2241950,2 Diff : 140,70
Run Code Online (Sandbox Code Playgroud)
我们希望.DotSettings在几种解决方案之间分享.我们的目标是有一个 CodeStyle.DotSettings,我们在我们所有的层参考X.sln.Dotsettings.但是,当我添加图层时,我看到了意外的行为.
我转到"管理选项",右键单击"解决方案X团队共享" - >"添加图层" - >"打开设置文件",选择CodeStyle.DotSettings并单击"打开".
然后我检查X.sln.DotSettings,看到两个引用,一个使用绝对路径,一个使用相对:
<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=3BE2D8150433584697322AAD3C173856/AbsolutePath/@EntryValue">C:\path\to\my\repo\CodeStyle.DotSettings</s:String>
<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=3BE2D8150433584697322AAD3C173856/RelativePath/@EntryValue">..\CodeStyle.DotSettings</s:String>
检查我的本地存储库的绝对路径是没有意义的,所以我尝试删除该行X.DotSettings,但它不再显示在"设置图层"对话框中.它的相对路径看起来很可疑,因此我尝试从中移除..\它,但它仍然没有出现在"设置层"中.
我究竟做错了什么?
我们正在使用ReSharper 8.2.3
这是value_or()C++ 17标准的定义:
template <class U> constexpr T value_or(U&& v) const&;效果:相当于:
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));备注:如果
is_copy_constructible_v<T> && is_convertible_v<U&&, T>是false,该程序是不正确的.
(右值超载类似)
效果value_or被描述为等同于return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
operator bool是noexcept.operator*是不是 noexcept(即使它没有抛出,可能是因为如果在可选项不包含值时使用UB,它仍然可以失败).但是,我们保证永远不会尝试返回包含的值,除非我们有一个.
所以不能value_or被宣布noexcept给予is_nothrow_copy_constructible<T> && noexcept(static_cast<T>(std::forward<U>(v)))?
鉴于此代码:
//header.h
template <class T>
class Foo
{
public:
Foo(T t) : t(t) {}
T t;
};
//source1.cpp:
#include "header.h"
extern template class Foo<int>;
int main()
{
Foo<int> f(42);
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,这个程序不应该链接,因为class Foo<int>任何地方都不应该有定义(extern template应该防止这个).使用VC++ 11(Visual Studio 2012),无论如何编译和链接.在海湾合作委员会,它没有:
source1.cpp:(.text+0x15): undefined reference to `Foo<int>::Foo(int)'
Run Code Online (Sandbox Code Playgroud)
如果我链接到source2.cpp但是它可以工作(正如我所期望的那样):
#include "header.h"
template class Foo<int>;
Run Code Online (Sandbox Code Playgroud)
根据这篇博文,自VC10以来应该支持extern模板. http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx
另外,有没有办法在Windows/Visual Studio上列出目标文件中的名称?在Linux上我会这样做:
$ nm source1.o
U _ZN3FooIiEC1Ei <- "U" means that this symbol is undefined.
0000000000000000 T main
Run Code Online (Sandbox Code Playgroud) 我希望为 C++ 应用程序构建一个非常简单的 GUI。花哨、设计和先进功能并不重要。然而,重要的是我可以针对它编写自动化测试,以编程方式检查字段内容并单击按钮。它还需要至少在 Linux 和 Windows 上运行,最好也可以在 Mac 上运行。有什么建议么?
编辑:开源工具是高度首选的。
我刚刚完成了一个非常困难的合并,但是在合并过程中的一段时间我做了一些导致 git 无法跟踪我正在合并的事实(我可能做了git reset什么)。
现在我在本地拥有的所有文件都已正确合并,但我无法完成合并,因为 git 不知道我正在合并。知道如何摆脱这个问题吗?合并花了很长时间,所以我不想再次手动进行。基本上我想完全保持本地状态,但只是通知 git 它应该创建一个合并提交(从当前分支和特定的其他分支)而不是常规提交。
c++ ×6
c++17 ×2
templates ×2
c# ×1
c++11 ×1
dead-code ×1
git ×1
java ×1
noexcept ×1
refactoring ×1
resharper ×1
stdoptional ×1
tdd ×1
visual-c++ ×1