小编May*_*rma的帖子

如何禁用GNU C扩展?

正如您在以下代码中看到的,我在以下代码中引入了嵌套函数main():

#include <stdio.h>

int main(){
 int a=5;
 printf("%d\n",a);
 {
  int a=10;
  printf("%d\n",a);
 }
 printf("%d\n",a);

 //Nested function
 int main(int a){
 if(a>0)printf("%d\n",a--);
 return 0;
 }

 main(7);
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

据我所知,我使用-std=c99gcc中的标志来"禁用"不必要的扩展,但我没有得到任何错误.

gcc temp3.c -std=c99 -o temp3.out

我在哪里弄错了?

c gcc

7
推荐指数
1
解决办法
3364
查看次数

退出()和C中main()函数的返回之间的区别

我查看了链接退出和退货有什么区别?在main()中返回语句vs exit() 来查找答案,但是徒劳无功.

第一个链接的问题是答案取决于return任何函数.我想知道在main()函数中两者之间的确切差异.即使有一点点差异,我也想知道它是什么.哪个是首选,为什么?在关闭各种编译器优化的情况下使用returnexit()(或exit()return)是否有任何性能提升?

第二个链接的问题是我对知道C++中发生的事情并不感兴趣.我想要特别关于C的答案.

编辑:经过一个人的推荐,我实际上试图比较以下程序的汇编输出:

注意:使用 gcc -S <myprogram>.c

程序mainf.c:

int main(void){
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

装配输出:

    .file   "mainf.c"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.9.2-10ubuntu13) 4.9.2"
    .section    .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)

程序mainf1.c:

#include <stdlib.h>

int main(void){
 exit(0);
}
Run Code Online (Sandbox Code Playgroud)

装配输出:

    .file   "mainf1.c" …
Run Code Online (Sandbox Code Playgroud)

c

6
推荐指数
3
解决办法
1500
查看次数

初始化与C中的赋值

我的导师最近告诉C中的数组初始化有两种方式,即:

  1. 手动喜欢 int a[5]={1,2,3,4,5};
  2. 使用scanf()int a[5], i; for(i=0;i<5;i++) scanf("%d", &a[i]);

在我看来,第二种"方式"是一种分配而不是初始化的方式.所以我决定检查这里的人们对此有何看法.我偶然发现了这个帖子,其中一个回答称:

如果您要问的是术语(*从您的问题中并不是很清楚),那么变量的"初始化"实际上是第一次为其赋值.这个术语来自于你给变量它的"初始"值.

这应该(显然)在第一次使用之前发生.

int x=5; 是一个声明和初始化,实际上只是方便的简写

int x; x=5;

如果我要遵循这个特定答案声称的内容,那么第二种"初始化"方式是正确的,因为在scanf()语句之前没有赋值.但是,由于我对静态变量的了解,我脑子里出现了一个新的疑问.请考虑以下代码:

#include <stdio.h>

void first_way(){
    static int x[2]={1,2};
    printf("first_way called %d time(s)\n",++x[0]);
}

void second_way(){
    int i;
    static int x[2];
    for(i=0;i<2;i++)scanf("%d",&x[i]);
    printf("second_way called %d time(s)\n",++x[0]);
}

int main(void){
    int i;
    for(i=0;i<3;i++)
        first_way();
    printf("\n#######\n");
    for(i=0;i<3;i++)
        second_way();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它的输出是这样的:

first_way called 2 time(s)
first_way called 3 time(s)
first_way called 4 …
Run Code Online (Sandbox Code Playgroud)

c language-lawyer

3
推荐指数
1
解决办法
1025
查看次数

C中的分段错误

#include <stdio.h>

int main()
{
    int n[100000];
    int t,q;
    int i,j;
    char s[3][100000];
    char qstr[3][200][100000];
    printf("Success\n");
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,大小qstr约为57.22 MiB.当仍有超过1 GiB的可用内存时,为什么会出现Segmentation故障?如果我更改声明,qstr因为qstr[3][200][10000]程序执行没有问题,实际打印"成功",然后退出.在这种情况下,'qstr'仅占据约5.7 MiB.

我有两个问题:

  1. 我怎么知道这个限制?

  2. 鉴于我有更多的可用内存,我该如何利用它?

c

0
推荐指数
1
解决办法
99
查看次数

为什么没有设置AF和SF?

我正在阅读Duntemann的书(第3版),刚刚开始学习x86汇编.我正在使用Fedora 23(64位)的变体.以下是代码:

section .data
section .text
    global  _start
_start:
    nop
; Put your experiments between the two nops...
    mov eax,0FFFFFFFFh
    mov ebx,02Dh
    dec ebx
    inc eax 
; Put your experiments between the two nops...
    nop
Run Code Online (Sandbox Code Playgroud)

我的makefile如下:

sandbox: sandbox.o
    ld -o sandbox sandbox.o -melf_i386
sandbox.o: sandbox.asm
    nasm -f elf -g -F stabs sandbox.asm -l sandbox.lst
Run Code Online (Sandbox Code Playgroud)

所以你可以看到我已经注意组装一个32位可执行文件,而不是64位.然而,问题在于,在dec ebx指令之前,AF并且SF没有设置标志与书所声称的相反.运行该程序insight向我显示32位寄存器,进一步确保可执行文件为32位.以下是gdbdec ebx指令之前显示的状态.

(gdb) info reg
eax            0xffffffff   -1
ecx            0x0  0
edx            0x0 …
Run Code Online (Sandbox Code Playgroud)

x86 assembly x86-64 nasm

0
推荐指数
1
解决办法
132
查看次数

标签 统计

c ×4

assembly ×1

gcc ×1

language-lawyer ×1

nasm ×1

x86 ×1

x86-64 ×1