艰难地学习 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 标签被调试宏使用。