‘new’未声明(在此函数内第一次使用),对‘operator new[](unsigned long)’未定义的引用,对‘operator delete[](void*)’未定义的引用,

36 篇文章 0 订阅
11 篇文章 0 订阅

Linux高性能服务器编程中源码 web_server_write.c

#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <sys/types.h>
#include <fcntl.h>

#define BUFFER_SIZE 1024


static const char * status_line[2] = {"200 OK","500 Internal server error"};

int main( int argc, char * argv[]){
    if(argc < 4){
        printf("%s needs three parameter \"ip\" and \"port\" and \"filename\"\n",argv[0]);
        return 1;
    }
    const char * ip = argv[1];
    int port = atoi(argv[2]);
    const char * file_name = argv[3];
    int servsock = socket(AF_INET, SOCK_STREAM, 0);
    assert(servsock>=0);
    int reuse = 1;
    setsockopt(servsock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
    struct sockaddr_in servaddr;
    memset(&servaddr, '\0', sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, ip, &servaddr.sin_addr);
    servaddr.sin_port = htons(port);

    int ret = bind(servsock, (struct sockaddr *)&servaddr, sizeof(servaddr));
    assert(ret != -1);

    ret = listen(servsock, 5);
    assert(ret != -1);
    
    struct sockaddr_in cliaddr;
    socklen_t cliaddrlen = sizeof(cliaddr);
    int connfd = accept(servsock, (struct sockaddr *)&cliaddr, &cliaddrlen);
    assert(connfd>=0);
    
    char header_buf[ BUFFER_SIZE ];
    memset(header_buf, '\0', BUFFER_SIZE);
    char * file_buf;
    struct stat file_stat;
    bool valid = true;
    int len = 0;
    if(stat(file_name, &file_stat) < 0){
        valid = false;
    }else{
        if(S_ISDIR(file_stat.st_mode)){
            valid = false;
        }else if(file_stat.st_mode & S_IROTH){
            int fd = open(file_name, O_RDONLY);
            file_buf = new char[file_stat.st_size + 1];
            memset(file_buf, '\0', file_stat.st_size + 1);
            if(read(fd, file_buf, file_stat.st_size)<0){
                valid = false;
            }
        }else{
            valid = false;
        }
    }

    if(valid){
        ret = snprintf(header_buf, BUFFER_SIZE-1, "%s %s\r\n","HTTP/1.1", status_line[0]);
        len += ret;
        ret = snprintf(header_buf+len, BUFFER_SIZE-1-len,"Content-Length:%d\r\n",file_stat.st_size);
        len += ret;
        ret = snprintf(header_buf + len, BUFFER_SIZE-1-len, "s%", "\r\n");

        struct iovec iv[2];
        iv[ 0 ].iov_base = header_buf;
        iv[ 1 ].iov_len = strlen( header_buf );
        iv[ 1 ].iov_base = file_buf;
        iv[ 1 ].iov_len = file_stat.st_size;
        ret = writev(connfd, iv, 2);
    }else{
        ret = snprintf(header_buf, BUFFER_SIZE-1, "%s %s\r\n", "HTTP/1.1", status_line[1]);
        len += ret;
        ret = snprintf(header_buf + len, BUFFER_SIZE-1-len, "%s", "\r\n");
        send(connfd, header_buf, strlen( header_buf ), 0);
    }
    close(connfd);
    delete [] file_buf;
    close(servsock);
    return 0;
}

 

gcc web_server_write.c -o web_server_write 

出现错误:

web_server_write.c:61:15: 错误:‘new’未声明(在此函数内第一次使用)
    file_buf = new char[file_stat.st_size + 1];
               ^
web_server_write.c:61:19: 错误:expected ‘;’ before ‘char’
    file_buf = new char[file_stat.st_size + 1];
                   ^
web_server_write.c:91:2: 错误:‘delete’未声明(在此函数内第一次使用)
  delete [] file_buf;
  ^
web_server_write.c:91:10: 错误:expected expression before ‘]’ token
  delete [] file_buf;

一顿百度后有提示说是c++,联想new关键字可能就是c++

mv   web_server_write.c web_server_write.cpp

gcc web_server_write.cpp -o web_server_write 

然后再次编译,出现错误:

/tmp/ccMNlxNF.o:在函数‘main’中:
web_server_write.cpp:(.text+0x263):对‘operator new[](unsigned long)’未定义的引用
web_server_write.cpp:(.text+0x476):对‘operator delete[](void*)’未定义的引用
collect2: 错误:ld 返回 1
然后再次百度,出现stackoverflow摘要,点进去一看。

大意说是

g++主要用来编译c++文件,g++编译c++文件是会连接libc++。

gcc主要用来编译c文件,也可编译c++,但gcc编译c++文件默认不连接libc++。

于是乎,改用g++

g++ web_server_write.cpp -o web_server_write

//编译通过,那么man gcc中提到可以编译c、c++文件的。根据stackoverflow大神们提供的有效答案。gcc也可以做到g++那样连接libc++

gcc -lstdc++  web_server_write.cpp -o web_server_write      // 注意加上   -lstdc++

编译也通过。

 

以下附上stackoverflow对g++与gcc区别的解释:

What is the difference between g++ and gcc? Which ones should be used for general c++ development?

1.

gcc and g++ are compiler-drivers of the 'Gnu Compiler Collection' (which was once upon a time just the 'Gnu C Compiler').

Even though they automatically determine which backends (cc1 cc1plus ...) to call depending on the file-type, unless overridden with -x language, they have some differences.

The probably most important difference in their defaults is which libraries they link against automatically.

According to GCC's online documentation link options and how g++ is invokedg++ is equivalent to gcc -xc++ -lstdc++ -shared-libgcc (the 1st is a compiler option, the 2nd two are linker options). This can be checked by running both with the -v option (it displays the backend toolchain commands being run).

2.

GCC: GNU Compiler Collection

  • Referrers to all the different languages that are supported by the GNU compiler.

gcc: GNU C      Compiler
g++: GNU C++ Compiler

The main differences:

  1. gcc will compile: *.c/*.cpp files as C and C++ respectively.
  2. g++ will compile: *.c/*.cpp files but they will all be treated as C++ files.
  3. Also if you use g++ to link the object files it automatically links in the std C++ libraries (gcc does not do this).
  4. gcc compiling C files has fewer predefined macros.
  5. gcc compiling *.cpp and g++ compiling *.c/*.cpp files has a few extra macros.

Extra Macros when compiling *.cpp files:

#define __GXX_WEAK__ 1
#define __cplusplus 1
#define __DEPRECATED 1
#define __GNUG__ 4
#define __EXCEPTIONS 1
#define __private_extern__ extern

 

  • 31

    You can link the std C++ library in gcc by passing -lstdc++ parameter. – Denilson Sá Maia Aug 23 '10 at 0:13

  • 15

    There are more differences between 'gcc' and 'g++' than only the standard libraries, so gcc -lstdc++will still not get you the same behavior as g++. We put all of that language-specific behavior into its own driver for a reason, that's what it's there for. :-) – Ti Strga Jan 28 '13 at 21:03

  • 8

    My comment isn't talking about just linking... that's the point. Even just restricting the discussion to linking (which your answer was not), a user still won't be able to use the entire C++ standard library by only specifying -lstdc++, as there will be missing dependencies on math, RTTI, and exception information. Whether a given test case links or fails will depend on the operating system and which C++ features are used by the test case, which again is why all of that knowledge is built into the g++ driver instead of being left up to the user to figure out. – Ti Strga Jan 29 '13 at 15:38

  • 9

    Trust me, we have this discussion a lot, usually when a Linux user tries to move his incomplete Makefile to another platform. :-) The g++ link stage does a lot more than gcc -lstdc++ on other OSes, especially when the target is an embedded platform. Fortunately, that's why we ship a g++ in the first place. – Ti StrgaJan 29 '13 at 15:40

  • 10

    The spec strings are constructed to be specific to the compiler, which in turn are specific to the operating system and target. So if you run -dumpspec on (for example) a cross compiler targeting an embedded system, you will see the differences. There are more than just linker differences... which again, is what your answer was about (preprocessor macros, include paths, multiple runtime libraries). We seem to be talking past each other, but as a former GCC maintainer, I assure you I am familiar with what the frontends are and are not. – Ti Strga Jan 29 '13 at 17:02 

3.

For c++ you should use g++.

It's the same compiler (e.g. the GNU compiler collection). GCC or G++ just choose a different front-end with different default options.

In a nutshell: if you use g++ the frontend will tell the linker that you may want to link with the C++ standard libraries. The gcc frontend won't do that (also it could link with them if you pass the right command line options).

4.

Although the gcc and g++ commands do very similar things, g++ is designed to be the command you'd invoke to compile a C++ program; it's intended to automatically do the right thing.

Behind the scenes, they're really the same program. As I understand, both decide whether to compile a program as C or as C++ based on the filename extension. Both are capable of linking against the C++ standard library, but only g++ does this by default. So if you have a program written in C++ that doesn't happen to need to link against the standard library, gcc will happen to do the right thing; but then, so would g++. So there's really no reason not to use g++ for general C++ development.

5.

What is the difference between g++ and gcc?

gcc has evolved from a single language "GNU C Compiler" to be a multi-language "GNU Compiler Collection". The term "GNU C Compiler" is still used sometimes in the context of C programming.

The g++ is the C++ compiler for the GNU Compiler Collection. Like gnat is the Ada compiler for gccsee Using the GNU Compiler Collection (GCC)

For example, the Ubuntu 16.04 man g++ command returns the GCC(1) manual page.

The man gcc states that ...

g++ accepts mostly the same options as gcc

and that the default ...

... use of gcc does not add the C++ library. g++ is a program that calls GCC and automatically specifies linking against the C++ library. It treats .c, .h and .i files as C++ source files instead of C source files unless -x is used. This program is also useful when precompiling a C header file with a .h extension for use in C++ compilations.

Search the gcc man pages for mores particulars on the option variances of gcc and g++.

Which one should be used for general c++ development?

Either gcc or g++ can be used for general C++ development with applicable option settings. However, g++ default behavior is more naturally aligned to a C++ centric development.

6.

I became interested in the issue and perform some experiments

  1. I found that description here, but it is very short.

  2. Then I tried to experiment with gcc.exe and g++.exe on my windows machine:

    $ g++ --version | head -n1 
    g++.exe (gcc-4.6.3 release with patches [build 20121012 by perlmingw.sf.net]) 4.6.3
    
    $ gcc --version | head -n1
    gcc.exe (gcc-4.6.3 release with patches [build 20121012 by perlmingw.sf.net]) 4.6.3
    
  3. I tried to compile c89, c99, and c++1998 simple test files and It's work well for me with correct extensions matching for language

    gcc -std=c99 test_c99.c
    gcc -std=c89 test_c89.c 
    g++ -std=c++98 test_cpp.cpp
    gcc -std=c++98 test_cpp.cpp
    
  4. But when I try to run "gnu compiler collection" tool in that fashion:

    $ gcc -std=c++98 test_cpp.c
    cc1.exe: warning: command line option '-std=c++98' is valid for C++/ObjC++ but not for C [enabled by default]
    
  5. But this one still work with no errors

    $ gcc -x c++ -std=c++98 test_cpp.c
    
  6. And this also

    $ g++ -std=c++0x test_cpp_11.cpp 
    

p.s. Test files

$ cat test_c89.c test_c99.c test_cpp.cpp

// C89 compatible file
int main()
{
    int x[] = {0, 2};
    return sizeof(x);
}

// C99 compatible file
int main()
{
    int x[] = {[1]=2};
    return sizeof(x);
}

// C++1998,2003 compatible file
class X{};
int main()
{
    X x;
    return sizeof(x);
}

// C++11
#include <vector>
enum class Color : int{red,green,blue}; // scoped enum
int main()
{
    std::vector<int> a {1,2,3}; // bracket initialization
    return 0;
}

Findings:

  1. If look at process tree then it seems that gcc, and g++ is backend to other tools, which in my environment are: cc1plus.exe, cc1.exe, collect2.exe, as.exe, ld.exe

  2. gcc works fine as metatool for if you have correct extension or set correct -std -x flags. See this

7.

The only notable difference is that i you pass a .c to gcc it will compile as C, whereas g++ will always treat it as C++

 

  • (Late, but for posterity,) As other answers have pointed out, this is by no means "the only notable difference", unless the reader has a skewed definition of notability. – underscore_d Sep 13 '15 at 21:54

8.

“GCC” is a common shorthand term for the GNU Compiler Collection. This is both the most general name for the compiler, and the name used when the emphasis is on compiling C programs (as the abbreviation formerly stood for “GNU C Compiler”).

When referring to C++ compilation, it is usual to call the compiler “G++”. Since there is only one compiler, it is also accurate to call it “GCC” no matter what the language context; however, the term “G++” is more useful when the emphasis is on compiling C++ programs.

You could read more here.

9.

I was testing gcc and g++ in a linux system. By using MAKEFILE, I can define the compliler used by "GNU make". I tested with the so called "dynamic memory" locating feature of "C plus plus" by :

int main(){

int * myptr = new int;
* myptr = 1;
printf("myptr[0] is %i\n",*myptr);
return 0;
}

Only g++ can successfully compile on my computer while gcc will report error

undefined reference to `operator new(unsigned long)'

So my own conclusion is gcc does not fully support "C plus plus". It seems that choosing g++ for C++ source files is a better option.

10.

gcc and g ++ are both GNU compiler. They both compile c and c++. The difference is for *.c files gcc treats it as a c program, and g++ sees it as a c ++ program. *.cpp files are considered to be c ++ programs. c++ is a super set of c and the syntax is more strict, so be careful about the suffix.

  • C++ is a different language, not a strict superset of C, so compiling with the wrong target language might well produce unexpected results. Also note that g++ will also interpret .cc as a C++-only filename extension. – underscore_d Sep 13 '15 at 21:51

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值