艰难地学习 C,Ex20 - Makefile 问题?
Learn C The Hard Way, Ex20 - Makefile Issue?
我一直在关注 Zed Shaw 的 Learn C The Hard Way,我已经练习了 20,可以在这里查看:http://c.learncodethehardway.org/book/ex20.html。我在 VirtualBox 上使用 Linux Mint KDE,我在 gedit 中编写代码,我在 Kate 中编写 makefile(出于语法原因 - 我在 gedit 中一直有错误)。
在编译代码时出现一些错误后,我只是简单地直接复制并粘贴它,看看我是否只是没有正确输入它,但我仍然有,使用 Valgrind,以下错误输出:
valgrind make ex20
==2715== Memcheck, a memory error detector
==2715== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==2715== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==2715== Command: make ex20
==2715==
cc -Wall -g -DNDEBUG ex20.c -o ex20
In file included from ex20.c:1:0:
dbg.h:1:0: error: unterminated #ifndef
#ifndef __dbg_h__
^
ex20.c: In function ‘test_debug’:
ex20.c:9:5: warning: implicit declaration of function ‘debug’ [-Wimplicit-function-declaration]
debug("I have Brown Hair.");
^
ex20.c: In function ‘test_log_err’:
ex20.c:17:5: warning: implicit declaration of function ‘log_err’ [-Wimplicit-function-declaration]
log_err("I believe everything is broken.");
^
ex20.c: In function ‘test_log_warn’:
ex20.c:23:5: warning: implicit declaration of function ‘log_warn’ [-Wimplicit-function-declaration]
log_warn("You can safely ignore this.");
^
ex20.c: In function ‘test_log_info’:
ex20.c:29:5: warning: implicit declaration of function ‘log_info’ [-Wimplicit-function-declaration]
log_info("Well I did something mundane.");
^
ex20.c: In function ‘test_check’:
ex20.c:39:5: warning: implicit declaration of function ‘check_mem’ [-Wimplicit-function-declaration]
check_mem(block); // should work
^
ex20.c:42:5: warning: implicit declaration of function ‘check’ [-Wimplicit-function-declaration]
check(input, "Failed to open %s.", file_name);
^
ex20.c:48:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
^
ex20.c: In function ‘test_sentinel’:
ex20.c:64:13: warning: implicit declaration of function ‘sentinel’ [-Wimplicit-function-declaration]
sentinel("I shouldn't run.");
^
ex20.c:70:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
^
ex20.c: In function ‘test_check_mem’:
ex20.c:83:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
^
ex20.c: In function ‘test_check_debug’:
ex20.c:90:5: warning: implicit declaration of function ‘check_debug’ [-Wimplicit-function-declaration]
check_debug(i != 0, "Oops, I was 0.");
^
ex20.c:93:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
^
ex20.c: In function ‘main’:
ex20.c:115:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
^
make: *** [ex20] Error 1
==2715==
==2715== HEAP SUMMARY:
==2715== in use at exit: 79,052 bytes in 1,433 blocks
==2715== total heap usage: 3,370 allocs, 1,937 frees, 205,837 bytes allocated
==2715==
==2715== LEAK SUMMARY:
==2715== definitely lost: 0 bytes in 0 blocks
==2715== indirectly lost: 0 bytes in 0 blocks
==2715== possibly lost: 0 bytes in 0 blocks
==2715== still reachable: 79,052 bytes in 1,433 blocks
==2715== suppressed: 0 bytes in 0 blocks
==2715== Rerun with --leak-check=full to see details of leaked memory
==2715==
==2715== For counts of detected and suppressed errors, rerun with: -v
==2715== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
根据他的 make 列出的输出,我决定 Makefile 应该如下所示:
CFLAGS=-Wall -g -DNDEBUG
all: ex20
clean:
rm -f ex20
如果有人能解释错误的原因(除了定义什么是隐式定义的函数——我知道),以及如何避免类似的错误,我将不胜感激。谢谢。
在以 #ifndef
(dbg.h
) 开头的文件末尾添加 #endif
。
ex20.c:64:13: warning: implicit declaration of function ‘sentinel’ [-Wimplicit-function-declaration]
sentinel("I shouldn't run.");
要解决此类错误,您应该在 .c 文件或 .h 文件的顶部添加函数原型。
参见 Function prototype
ex20.c:93:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
很明显您定义了一个标签 error:
但您没有使用它。
首先,正如评论中所提到的,您不需要 运行 在 valgrind 中进行 make - 除非您实际上是在调试/测试 make 本身,因此要构建您的程序,您只需这样做:
make ex20
然后你可以运行它:
./ex20
或运行它在valgrind下:
valgrind ./ex20
如果您愿意,您可以将规则添加到 运行 的 makefile 中,如下所示:
CFLAGS=-Wall -g -DNDEBUG
all: ex20
run: ex20
./ex20
grind: ex20
valgrind ./ex20
clean:
rm -f ex20
请注意,这不包括实际构建 ex20 的方法——尽管您的问题中也没有显示该方法
其次,我们仍然可以看到编译器错误。修复编译器错误和警告的主要规则是从顶部开始,这里的第一个错误是
In file included from ex20.c:1:0:
dbg.h:1:0: error: unterminated #ifndef
#ifndef __dbg_h__
这实际上非常有用。我们可以看到 dbg.h 使用包含保护来防止同一个 header 被单个 .c 文件多次包含,但是看起来没有终止 #endif
。典型的结构是这样的
#ifndef __headername_h
#define __headername_h
//Lots of header content
#endif
您可能可以通过在文件末尾添加#endif 来解决此问题,但也有可能是某些内容进一步不同步。但是如果 header 文件没有以 #endif 结尾,那几乎肯定是问题所在。
修复它,然后重新编译。您可能会发现其他 warnings/errors 消失了 - 谁知道第一个错误的影响是什么。如果不知道函数所在的 header 文件,并包含它。
未使用的标签也可能是第一个错误的副作用。代码中的 :error 标签被调试宏使用。
我一直在关注 Zed Shaw 的 Learn C The Hard Way,我已经练习了 20,可以在这里查看:http://c.learncodethehardway.org/book/ex20.html。我在 VirtualBox 上使用 Linux Mint KDE,我在 gedit 中编写代码,我在 Kate 中编写 makefile(出于语法原因 - 我在 gedit 中一直有错误)。
在编译代码时出现一些错误后,我只是简单地直接复制并粘贴它,看看我是否只是没有正确输入它,但我仍然有,使用 Valgrind,以下错误输出:
valgrind make ex20
==2715== Memcheck, a memory error detector
==2715== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==2715== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==2715== Command: make ex20
==2715==
cc -Wall -g -DNDEBUG ex20.c -o ex20
In file included from ex20.c:1:0:
dbg.h:1:0: error: unterminated #ifndef
#ifndef __dbg_h__
^
ex20.c: In function ‘test_debug’:
ex20.c:9:5: warning: implicit declaration of function ‘debug’ [-Wimplicit-function-declaration]
debug("I have Brown Hair.");
^
ex20.c: In function ‘test_log_err’:
ex20.c:17:5: warning: implicit declaration of function ‘log_err’ [-Wimplicit-function-declaration]
log_err("I believe everything is broken.");
^
ex20.c: In function ‘test_log_warn’:
ex20.c:23:5: warning: implicit declaration of function ‘log_warn’ [-Wimplicit-function-declaration]
log_warn("You can safely ignore this.");
^
ex20.c: In function ‘test_log_info’:
ex20.c:29:5: warning: implicit declaration of function ‘log_info’ [-Wimplicit-function-declaration]
log_info("Well I did something mundane.");
^
ex20.c: In function ‘test_check’:
ex20.c:39:5: warning: implicit declaration of function ‘check_mem’ [-Wimplicit-function-declaration]
check_mem(block); // should work
^
ex20.c:42:5: warning: implicit declaration of function ‘check’ [-Wimplicit-function-declaration]
check(input, "Failed to open %s.", file_name);
^
ex20.c:48:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
^
ex20.c: In function ‘test_sentinel’:
ex20.c:64:13: warning: implicit declaration of function ‘sentinel’ [-Wimplicit-function-declaration]
sentinel("I shouldn't run.");
^
ex20.c:70:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
^
ex20.c: In function ‘test_check_mem’:
ex20.c:83:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
^
ex20.c: In function ‘test_check_debug’:
ex20.c:90:5: warning: implicit declaration of function ‘check_debug’ [-Wimplicit-function-declaration]
check_debug(i != 0, "Oops, I was 0.");
^
ex20.c:93:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
^
ex20.c: In function ‘main’:
ex20.c:115:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
^
make: *** [ex20] Error 1
==2715==
==2715== HEAP SUMMARY:
==2715== in use at exit: 79,052 bytes in 1,433 blocks
==2715== total heap usage: 3,370 allocs, 1,937 frees, 205,837 bytes allocated
==2715==
==2715== LEAK SUMMARY:
==2715== definitely lost: 0 bytes in 0 blocks
==2715== indirectly lost: 0 bytes in 0 blocks
==2715== possibly lost: 0 bytes in 0 blocks
==2715== still reachable: 79,052 bytes in 1,433 blocks
==2715== suppressed: 0 bytes in 0 blocks
==2715== Rerun with --leak-check=full to see details of leaked memory
==2715==
==2715== For counts of detected and suppressed errors, rerun with: -v
==2715== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
根据他的 make 列出的输出,我决定 Makefile 应该如下所示:
CFLAGS=-Wall -g -DNDEBUG
all: ex20
clean:
rm -f ex20
如果有人能解释错误的原因(除了定义什么是隐式定义的函数——我知道),以及如何避免类似的错误,我将不胜感激。谢谢。
在以 #ifndef
(dbg.h
) 开头的文件末尾添加 #endif
。
ex20.c:64:13: warning: implicit declaration of function ‘sentinel’ [-Wimplicit-function-declaration]
sentinel("I shouldn't run.");
要解决此类错误,您应该在 .c 文件或 .h 文件的顶部添加函数原型。 参见 Function prototype
ex20.c:93:1: warning: label ‘error’ defined but not used [-Wunused-label]
error:
很明显您定义了一个标签 error:
但您没有使用它。
首先,正如评论中所提到的,您不需要 运行 在 valgrind 中进行 make - 除非您实际上是在调试/测试 make 本身,因此要构建您的程序,您只需这样做:
make ex20
然后你可以运行它:
./ex20
或运行它在valgrind下:
valgrind ./ex20
如果您愿意,您可以将规则添加到 运行 的 makefile 中,如下所示:
CFLAGS=-Wall -g -DNDEBUG
all: ex20
run: ex20
./ex20
grind: ex20
valgrind ./ex20
clean:
rm -f ex20
请注意,这不包括实际构建 ex20 的方法——尽管您的问题中也没有显示该方法
其次,我们仍然可以看到编译器错误。修复编译器错误和警告的主要规则是从顶部开始,这里的第一个错误是
In file included from ex20.c:1:0:
dbg.h:1:0: error: unterminated #ifndef
#ifndef __dbg_h__
这实际上非常有用。我们可以看到 dbg.h 使用包含保护来防止同一个 header 被单个 .c 文件多次包含,但是看起来没有终止 #endif
。典型的结构是这样的
#ifndef __headername_h
#define __headername_h
//Lots of header content
#endif
您可能可以通过在文件末尾添加#endif 来解决此问题,但也有可能是某些内容进一步不同步。但是如果 header 文件没有以 #endif 结尾,那几乎肯定是问题所在。
修复它,然后重新编译。您可能会发现其他 warnings/errors 消失了 - 谁知道第一个错误的影响是什么。如果不知道函数所在的 header 文件,并包含它。
未使用的标签也可能是第一个错误的副作用。代码中的 :error 标签被调试宏使用。