有谁知道一个生产有价值的包商业或OSS可以检测哪些代码行已被执行?
我们正在寻找一些可以帮助我们在生产环境中检测死代码的工具,运行Ruby On Rails 1.8.7
-daniel
以下代码在Eclipse中给出了一个"死代码"警告:
private void add(Node<E> n, E element) {
Node<E> e = new Node<E>(element);
if (n == null)
root = e;
else if (n.compareTo(e) > 0)
if (n.hasLeft())
add(n.getLeft(), element);
else
n.setLeft(e);
else if (n.hasRight())
add(n.getRight(), element);
else
n.setRight(e);
balance(e);
}
Run Code Online (Sandbox Code Playgroud)
警告出现在说明的那一行root = e;.
我查了死代码,发现代码帽没有效果,因此会被java编译器忽略.
但是,这个root是我班级中的私有字段,因此我的程序功能是必要的.
编译器真的会忽略这个吗?我怎么能阻止它?为什么它认为它是死代码?
我很难找到有关javac代码消除功能的信息:
我读到如果你有类似下面这样的东西,那么if-statement将被淘汰:
static final boolean DEBUG = false;
if (DEBUG) System.out.println("Hello World!"); // will be removed
Run Code Online (Sandbox Code Playgroud)
但是这个怎么样,例如:
static final int VALUE = 3;
if (VALUE > 9) System.out.println("VALUE > 9 ???"); // will this be removed?
Run Code Online (Sandbox Code Playgroud)
或这个:
static final SomeEnum VALUE = SomeEnum.FOO;
if (VALUE==SomeEnum.BAR) System.out.println("Bar???"); // will this be removed?
Run Code Online (Sandbox Code Playgroud)
由于分析程序以查找所有死代码(可能类似于暂停问题)非常困难/不可能,因此我认为只有少数明确定义的构造(如上面的第一个示例),javac它将识别并删除可靠.是否有这些结构的完整列表?
对我正在写的某个班级来说,表现很重要.
我想过调用这样的函数:
debug('This is a debug message, only visible when debugging is on');
Run Code Online (Sandbox Code Playgroud)
内容就像
function debug(message) {
if (DEBUG) console.log(message);
}
Run Code Online (Sandbox Code Playgroud)
所以我想知道:如果DEBUG变量永远不变,V8是否足以将其标记为"死代码" ?
编辑:我更担心Node中的性能而不是浏览器,因此在缩小时删除代码是不够的.
Edit2:我从提议的解决方案中做了一个JSPerf基准测试,它们非常令人惊讶:http://jsperf.com/verbose-debug-loggin-conditionals-functions-and-no-ops/3
考虑以下代码:
@Test
public void testDeadCode() {
letsThrow();
System.out.println("will never be reached");
}
private final void letsThrow() {
throw new RuntimeException("guess you didnt see this one coming");
}
Run Code Online (Sandbox Code Playgroud)
对我来说,println()似乎绝对不可能执行 - 因为对letsThrow()的调用将始终抛出异常.
我就是这样
a)惊讶于编译器无法告诉我"这是死代码"
b)想知道是否有一些编译器标志(或eclipse设置)会告诉我:你那里有死代码.
我有以下代码:
public String myMethod(String keyValue) {
Map<String, Integer> keyValueToRowIndex = ...
Integer rowIndex = (keyValue == null) ? 0 : keyValueToRowIndex.get(keyValue);
if (rowIndex == null)
return null;
...
}
Run Code Online (Sandbox Code Playgroud)
Eclipse给出了"死代码"警告return null;.删除测试keyValue == null也删除了警告,但我没有看到额外的测试如何使return语句死代码.显然,如果地图中没有包含某些非null的条目keyValue,那么rowIndex仍然可以为null.或者我在这里遗漏了什么?
我已经看到了类似的Eclipse问题(例如这里),但这个问题似乎是一个不同的,更简单的问题.
为了重构客户端项目,我正在寻找一种安全的方法来查找(和删除)未使用的代码。
您使用什么工具在大型React项目中查找未使用/无效的代码?我们的产品已经开发了几年,并且很难手动检测不再使用的代码。但是,我们确实尝试删除尽可能多的未使用的代码。
对于一般策略/技术(除特定工具之外)的建议也将受到赞赏。
谢谢
我使用 Vite 捆绑器,在我的代码中我有以下功能:
function doSomething() {
if (!import.meta.env.VITE_SOMETHING) {
return;
}
console.log("Hello");
}
Run Code Online (Sandbox Code Playgroud)
我希望在构建我的应用程序(npm run build)而不定义VITE_SOMETHING环境变量后,我将Hello在代码中看到没有日志记录,但我看到了。
更糟糕的是,在我使用的每个地方,import.meta.env.VITE_SOMETHING我都在编译的输出中看到{BASE_URL:"/",MODE:"production",DEV:!1,PROD:!0}.VITE_SOMETHING。它看起来不是很理想。
是否可以共同配置 Vite 来优化输出 - 删除未使用的代码和重复项(它引入的)?
假设我有以下文件:
libmy_static_lib.c:
#include <stdio.h>
void func1(void){
printf("func1() called from a static library\n");
}
void unused_func1(void){
printf("printing from the unused function1\n");
}
void unused_func2(void){
printf("printing from unused function2\n");
}
Run Code Online (Sandbox Code Playgroud)
libmy_static_lib.h:
void func(void);
void unused_func1(void);
void unused_func2(void);
Run Code Online (Sandbox Code Playgroud)
my_prog.c:
#include "libmy_static_lib.h"
#include <stdio.h>
void func_in_my_prog()
{
printf("in my prog\n");
func1();
}
Run Code Online (Sandbox Code Playgroud)
这是我链接库的方式:
# build the static library libmy_static_lib.a
gcc -fPIC -c -fdata-sections --function-sections -c libmy_static_lib.c -o libmy_static_lib.o
ar rcs libmy_static_lib.a libmy_static_lib.o
# build libmy_static_lib.a into a new shared library
gcc -fPIC -c ./my_prog.c …Run Code Online (Sandbox Code Playgroud) tl;dr:能否以某种方式确保(例如通过编写单元测试)某些东西被优化掉,例如整个循环?
确保生产版本中不包含某些内容的常用方法是将其包装为#if...#endif. 但我更喜欢继续使用 C++ 机制。即使在那里,我也喜欢保持简单的实现,而不是复杂的模板专业化,并认为“嘿,编译器无论如何都会优化它”。
上下文是汽车中的嵌入式软件(二进制大小很重要),编译器通常很差。它们在安全意义上得到了认证,但通常在优化方面表现不佳。
示例 1:在容器中,元素的销毁通常是一个循环:
for(size_t i = 0; i<elements; i++)
buffer[i].~T();
Run Code Online (Sandbox Code Playgroud)
这也适用于内置类型,例如int,因为标准允许显式调用任何标量类型的析构函数 (C++11 12.4-15)。在这种情况下,循环不执行任何操作并被优化掉。在 GCC 中是这样,但在另一个(Aurix)中不是,我在反汇编中看到了一个字面上的空循环!因此需要模板专门化来修复它。
示例 2:代码,仅用于调试、分析或故障注入等:
constexpr bool isDebugging = false; // somehow a global flag
void foo(int arg) {
if( isDebugging ) {
// Albeit 'dead' section, it may not appear in production binary!
// (size, security, safety...)
// 'if constexpr..' not an option (C++11)
std::cout << "Arg was " << arg << std::endl;
}
// …Run Code Online (Sandbox Code Playgroud) dead-code ×10
java ×4
javascript ×3
eclipse ×2
refactoring ×2
c ×1
c++ ×1
c++11 ×1
debugging ×1
gcc ×1
javac ×1
node.js ×1
optimization ×1
reactjs ×1
ruby ×1
unit-testing ×1
vite ×1