include问题及错误解决

http://blog.csdn.net/pipisorry/article/details/38512433

sudo make时#include "hdfs.h"出现include错误

fatal error: hdfs.h: No such file or directory 

#include "hdfs.h"

也就是hdfs.h文件inclucd不进来

原因:

文件读取权限问题,$HADOOP_HOME/include目录是用户bdms安装的,则另一个普通用户如guest则不能读取,即使echo $CLASSPATH有这个目录。

解决:

使用super用户source配置文件,并在super用户下make

# vi bin/setenv

export CLASSPATH=$CLASSPATH:`$HADOOP_HOME/bin/hadoop classpath --glob`:$HADOOP_HOME/include

# . bin/setenv 

# echo $CLASSPATH

...:/usr/local/java/hadoop-2.6.0/include

皮皮blog



g++无法使用数学库函数,abs() 函数无法找到

同样的一个源码, 如果保存成c文件, 用gcc编译可以通过和使用

如果用g++编译无法通过. 原因是abs() 函数无法找到? 

解决:

#include

皮皮blog



C/C++避免同一个文件被include多次的两种方式

一种是#ifndef方式,一种是#pragma once方式:

    方式一:
    #ifndef __SOMEFILE_H__
    #define __SOMEFILE_H__
    ... ... // 声明、定义语句
    #endif


    方式二:

    #pragma once

    ... ... // 声明、定义语句


   #ifndef的方式受C/C++语言标准支持。它不光可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。
    当然,缺点就是如果不同头文件中的宏名不小心“撞车”,可能就会导致你看到头文件明明存在,编译器却硬说找不到声明的状况——这种情况有时非常让人抓狂。
    由于编译器每次都需要打开头文件才能判定是否有重复定义,在包含一个文件的时候,只有打开这个文件,根据文件的保护宏是否已经被定义来判断此文件是否已经被包含过,所以效率相对较低。

因此在编译大型项目时,ifndef会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式。


   #pragma once一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。

   效率更高:因为不需要去打开包含的文件,就可以判断这个文件有没有被包含,当然这个工作是系统帮我们完成的。

    其好处是,你不必再费劲想个宏名了,当然也就不会出现宏名碰撞引发的奇怪问题。大型项目的编译速度也因此提高了一些。
    对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名碰撞引发的“找不到声明”的问题,这种重复包含很容易被发现并修正。

    #pragma once方式产生于#ifndef之后,目前看来#ifndef更受到推崇。因为#ifndef受C/C++语言标准的支持,不受编译器的任何限制;而#pragma once方式却不受一些较老版本的编译器支持,一些支持了的编译器又打算去掉它,所以它的兼容性可能不够好。一般而言,当程序员听到这样的话,都会选择#ifndef方式,为了努力使得自己的代码“存活”时间更久,通常宁愿降低一些编译性能。



还有一种用法是把两者放在一起的:

    #pragma once
    #ifndef __SOMEFILE_H__
    #define __SOMEFILE_H__
    ... ... // 声明、定义语句
    #endif

    看起来似乎是想兼有两者的优点。不过只要使用了#ifndef就会有宏名冲突的危险,也无法避免不支持#pragma once的编译器报错,所以混用两种方法似乎不能带来更多的好处,倒是会让一些不熟悉的人感到困惑。


在#include的时候,程序员也可以自己判断所要包含的文件的保护宏是否已经被定义,来决定是否要包含这个文件。类似下面的代码:

[cpp]  view plain copy
  1. #ifndef FILE_H_  
  2.     #include "file.h"  
  3. #endif  
这样作可以得到较高的效率,而且保证可移植性。但是文件之间的依赖性较高,如果一个文件的保护宏改变的话,所有使用如上形式包含这个文件的文件都要修改,有悖于模块化的思想。


附:如何保证使用的标识符在其他地方没有使用过?

   /* things.h */
#ifndef THINGS_H_
        #define THINGS_H_
        ...
#endif

     通常编译器提供商采用如下方法:用文件名作为标识符,并在文件名中使用大写字母。用下划线代替文件名中的句点符号,用下划线(可能两条下划线)作前缀和后缀。

     所以,为了避免跟编译器提供的头文件相冲突,采取的方法是把编译器标识符去掉前缀,也就是前缀不用下划线,其他按照编译器的方法。上面的示例就是采用的这种方法。

[http://blog.csdn.net/holybin/article/details/28397157

http://zhangzhiyin1982.blog.163.com/blog/static/2899121720076259553175/

http://blog.csdn.net/hkx1n/article/details/4313303]

from: http://blog.csdn.net/pipisorry/article/details/38512433

ref:


你可能感兴趣的:(C++)