学习C艰难之路,Ex20-Makefile问题



我一直在学习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)

根据他制作的输出,我决定Makefile应该如下:

CFLAGS=-Wall    -g  -DNDEBUG
all: ex20   
clean:
    rm  -f  ex20

如果有人能解释我得到的错误的原因(除了定义隐式定义的函数是什么——我知道),以及如何避免类似的错误,我将不胜感激。非常感谢。

在以#ifndefdbg.h)开头的文件末尾添加#endif

ex20.c:64:13: warning: implicit declaration of function ‘sentinel’ [-Wimplicit-function-declaration]
                 sentinel("I shouldn't run.");

要解决这种错误,您应该在.c文件的顶部或.h文件中添加函数的原型。参见功能原型

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使用include保护来防止同一个头被单个.c文件多次包含,但看起来并没有终止#endif。典型的结构如

#ifndef __headername_h
#define __headername_h
//Lots of header content
#endif

您可能可以通过在文件末尾添加#endif来解决此问题,但也有可能是某些内容进一步不同步。但是,如果头文件没有以#endif结尾,那几乎可以肯定是问题所在。

修复该问题,然后重新编译。你可能会发现其他警告/错误消失了——谁知道第一个错误的影响是什么。如果没有弄清楚函数在哪个头文件中,并将其包括在内。

未使用的标签也可能是第一个错误的副作用。代码中的:error标签由调试宏使用。

最新更新