在C main参数中使用long **而不是char **

时间:2015-08-28 05:44:33

标签: c

我试图将主要参数中的char **替换为long **。但是,编译器通过以下警告抱怨它:

> add2.c:3:5: error: second parameter of 'main' (argument array) must be
>       of type 'char **' int main(int i, long **a) {

无论如何,我可以通过添加一些gcc标志来编译这段代码吗?

由于这篇文章收到了太多的反对票,我想更多地解释为什么我在问这个问题。我有这个问题,因为我在CTF(夺旗)练习比赛中遇到了这个问题。我认为这可能值得一提,因为 它可以让人们更多地了解C main函数中的参数

  1. 我已经google了一下,从未见过这个问题之前被问过(每个人都接受char **作为C main函数的参数)

  2. 我们可以使用GCC标志禁用检查,这可以帮助其他人了解GCC可以做多少事情

  3. 我很抱歉这个问题收到了这么多的支持,我不知道为什么人们会贬低这个。我仍然认为这个问题值得讨论。

    我在服务器SUCCESSFULLY上运行了这段代码,我在这里发布了我的结果作为答案。如果有人知道如何做这项工作,我会很高兴听到这个。

    level3@io64:/tmp$ cat add2.c
    #include <unistd.h>
    
    int main(int i, long **a) {
        if(*a[1] * 0xabcdabcdabcdu == 0x123412341234u)
            execl("/bin/sh", "sh", 0);
        return 0;
    }
    level3@io64:/tmp$ gcc -o a add2.c
    /usr/bin/ld: cannot open output file a: Permission denied
    collect2: error: ld returned 1 exit status
    level3@io64:/tmp$ gcc add2.c
    /usr/bin/ld: cannot open output file a.out: Permission denied
    collect2: error: ld returned 1 exit status
    level3@io64:/tmp$ gcc -o abc add2.c
    level3@io64:/tmp$ gcc -v -o abcd add2.c
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-5' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
    Thread model: posix
    gcc version 4.7.2 (Debian 4.7.2-5)
    COLLECT_GCC_OPTIONS='-v' '-o' 'abcd' '-mtune=generic' '-march=x86-64'
     /usr/lib/gcc/x86_64-linux-gnu/4.7/cc1 -quiet -v -imultiarch x86_64-linux-gnu add2.c -quiet -dumpbase add2.c -mtune=generic -march=x86-64 -auxbase add2 -version -o ./ccyNP1XF.s
    GNU C (Debian 4.7.2-5) version 4.7.2 (x86_64-linux-gnu)
        compiled by GNU C version 4.7.2, GMP version 5.0.5, MPFR version 3.1.0-p10, MPC version 0.9
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=100000
    ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
    ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/include"
    #include "..." search starts here:
    #include <...> search starts here:
     /usr/lib/gcc/x86_64-linux-gnu/4.7/include
     /usr/local/include
     /usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed
     /usr/include/x86_64-linux-gnu
     /usr/include
    End of search list.
    GNU C (Debian 4.7.2-5) version 4.7.2 (x86_64-linux-gnu)
        compiled by GNU C version 4.7.2, GMP version 5.0.5, MPFR version 3.1.0-p10, MPC version 0.9
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=100000
    Compiler executable checksum: 7fa7c2a970be5e19ce72b2057c14800d
    COLLECT_GCC_OPTIONS='-v' '-o' 'abcd' '-mtune=generic' '-march=x86-64'
     as -v --64 -o ./ccJEfzc6.o ./ccyNP1XF.s
    GNU assembler version 2.22 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.22
    COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/
    LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../:/lib/:/usr/lib/
    COLLECT_GCC_OPTIONS='-v' '-o' 'abcd' '-mtune=generic' '-march=x86-64'
     /usr/lib/gcc/x86_64-linux-gnu/4.7/collect2 --sysroot=/ --build-id --no-add-needed --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o abcd /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.7 -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../.. ./ccJEfzc6.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.7/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crtn.o
    

4 个答案:

答案 0 :(得分:4)

这是唯一允许的主要声明,没有int main(int i, long **a),我们无法发明一个,因为它根本不受支持。

来自C ++标准,

  

3.6.1主要功能

     

实现不应预定义主函数。 此功能   不应该重载。它的返回类型应为int,但是   否则其类型是实现定义的。所有实施   

     

- ()返回int和

的函数      

- 一个函数(int,指向char的指针)返回int

答案 1 :(得分:3)

这取决于您为此编译的系统。在托管环境中,通常不允许更改main的参数。如果您要更改它们,编译器必须支持它并记录方式。

  • GCC不支持我所知道的任何gcc端口中main()的非标准参数。
  • 没有编译器允许程序员发明他们自己的,疯狂的main()格式。如果存在这样的编译器,它将不遵循C和C ++标准。

Complete reference for the allowed forms of main in C and C++

答案 2 :(得分:0)

根据C和C ++规范,操作系统,shell,编译器和启动代码共同工作,将void MyListView::somethingIsSelected() { const auto selectedIdxs = selectedIndexes(); if (!selectedIdxs.isEmpty()) { const QVariant var = model()->data(selectedIdxs.first()); // next you need to convert your `var` from `QVariant` to something that you show from your data with default (`Qt::DisplayRole`) role, usually it is a `QString`: const QString selectedItemString = var.toString(); // or you also may do this by using `QStandardItemModel::itemFromIndex()` method: const QStandardItem* selectedItem = dynamic_cast<QStandardItemModel*>(model())->itemFromIndex(selectedIdxs.first()); // use your `QStandardItem` } } 作为第二个参数传递给char **

如果要将第二个参数更改为main,则需要编写

  • 您自己的操作系统
  • 你自己的外壳
  • 您自己的编译器和
  • 您自己的启动代码

祝你好运!你完成后我们会在50年后见到你。

答案 3 :(得分:0)

我在服务器上对此进行了测试(我无法在我的机器上运行此代码)。显然,参数a像char一样存储在堆栈中。

如果我正在调用我的程序

./a 12345678 

并以十六进制格式打印出* a [1],我得到了值0x3837363534333231我会说程序没有考虑我的输入,即使参数类型很长。

通常的方法是将argv设置为char **类型并使用指针将其强制转换为long。

我希望这可以帮助那些遇到同样问题的人,如果你有想法可以编译这些代码,请告诉我。

根据提供的所有答案/评论/ c规范,似乎不可能这样做。