Почему не выполняет функцию printf внутри?

Следующий код компилируется и запускается на компиляторе GCC.

#include <stdio.h>

 int arr[10];

 int func()
 {
      printf("In func\n");
      return 0;
 }

int main() 
{
    if (&arr[func()])
        printf("In main\n");
     return 0;
}

Выход:

In main

Почему не запускает printf("In func\n");?

Что делает эта строка кода if (&arr[func()])? Когда адрес любого элемента arr станет нулевым? Вы уверены, что в вашем коде нет управляющих символов DOS? Получаете какие-либо предупреждения компилятора? Какие?

David C. Rankin 13.03.2018 06:29

Скомпилируйте свой код со всеми предупреждениями и отладочной информацией: gcc -Wall -Wextra -g. Тогда использовать отладчик gdb. Вы должны наблюдать за printf.

Basile Starynkevitch 13.03.2018 06:37

Или, по крайней мере, убедитесь, что вы «сохранили» после публикации кода, затем скомпилируйте с включенными предупреждениями и продолжайте.

David C. Rankin 13.03.2018 06:38

Я просто вставил ваш код и получил In func/In main. (gcc 5.4.0)

lockcmpxchg8b 13.03.2018 06:38

Даже действительно умный оптимизатор может узнать только то, что проверка всегда отлична от нуля, поэтому он должен вызвать побочный эффект.

lockcmpxchg8b 13.03.2018 06:41

Я скомпилировал и визуализировал ваш код, он работает, и оба отпечатка распечатываются должным образом. в чем смысл утверждения if, он всегда оценивается как истина, поскольку &arr[func()] - это адрес arr[0]. какой компилятор вы используете?

Omer Dagan 13.03.2018 06:44

Давайте сделаем небольшое изменение, чтобы предотвратить оптимизацию func() с помощью gcc ... int *p = &arr[func()]; if (p) printf("In main\n"); и повторите попытку.

David C. Rankin 13.03.2018 06:55

@Jayesh: Я думаю, вы просто неправильно скомпилировали свою программу. Пожалуйста, дайте фактическую команду компиляции, которую вы набрали в терминале

Basile Starynkevitch 13.03.2018 07:00

@BasileStarynkevitch, это действительно проблема gcc. В gcc 7.3 func() полностью оптимизирован из main(). Несмотря на то, что он производит вывод. Более ранние версии gcc справляются с этим нормально. Действительно странно. .string "In func" сохранен, функция func() есть, но она полностью опущена при генерации кода для main:, так что @Jayesh не сумасшедший.

David C. Rankin 13.03.2018 07:02

@ DavidC.Rankin: При компиляции с gcc -Wall -g jayesh.c -o jayesh я наблюдаю два выхода, с gcc 7.3 на Debian / Sid. И даже с gcc -O -Wall -g jayesh.c -o jayesh вывод тоже наблюдаю. И даже с -O3; если бы это было не так, это было бы серьезной ошибкой оптимизации. Поэтому мы не можем воспроизвести ваше наблюдение.

Basile Starynkevitch 13.03.2018 07:07

Я скомпилировал последнее ядро ​​4.15.8 с помощью gcc 7.3.0, и его больше нет. Это странно. Выложу сборку.

David C. Rankin 13.03.2018 07:10

Укажите, известно ли вам о содержании ссылки, предоставленной @PkmX в своем ответе. Сходство примеров кода поразительно. Если вы пытаетесь протестировать StackOverflowers, я голосую за PkmX.

Yunnosch 13.03.2018 09:05
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
12
898
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Проблема в твоей компиляции. Я использую gcc для компиляции. Я скомпилировал ваш файл так:

gcc main.c -o prog
./prog
In func
In main

Мне кажется, это хорошо. Проверьте процедуру компиляции с вашим компилятором, если вы используете компилятор, отличный от gcc. Также использую gcc 7.3

А с GCC 7.3 такой же вывод происходит с -O, -O2, -O3.

Basile Starynkevitch 13.03.2018 07:07

GCC 7.3.0 на Mac показывает мне ошибку (как эта версия, так и версия из GCC Bug # 84607 - с -O0, -O1, -O2 или -O3.

Jonathan Leffler 13.03.2018 09:35
Ответ принят как подходящий

Кажется, есть тонкая проблема, преднамеренная или непреднамеренная, с различными комбинациями последней версии gcc. версия 7.3 в последней версии ядра 4.15.8 на Archlinux. По какой-то причине вызов func() опущен для кода, сгенерированного для main(). например

$ gcc -S -masm=intel -o infunc2.asm infunc2.c

Сгенерированная сборка:

$ cat infunc2.asm
        .file   "infunc2.c"
        .intel_syntax noprefix
        .text
        .comm   arr,40,32
        .section        .rodata
.LC0:
        .string "In func"
        .text
        .globl  func
        .type   func, @function
func:
.LFB0:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        lea     rdi, .LC0[rip]
        call    puts@PLT
        mov     eax, 0
        pop     rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   func, .-func
        .section        .rodata
.LC1:
        .string "In main"
        .text
        .globl  main
        .type   main, @function
main:
.LFB1:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        lea     rdi, .LC1[rip]
        call    puts@PLT
        mov     eax, 0
        pop     rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1:
        .size   main, .-main
        .ident  "GCC: (GNU) 7.3.0"
        .section        .note.GNU-stack,"",@progbits

Обратите внимание, что вызов func() обозначен выше как .LFB0:. Процедура для main: вообще не вызывает func или .LFB0:, несмотря на то, что они присутствуют, и несмотря на то, что строка "In func" присутствует в .LC0:. Я подозреваю, что это ненормальное поведение.

Например, при простой компиляции без оптимизации -O0 функция не вызывается, например:

$ gcc -g -O0 -o bin/if2 infunc2.c
$ ./bin/if2
In main

Изменение кода для сохранения адреса arr[func()] вызывает принудительный вызов func(), например

#include <stdio.h>

int arr[10];

int func()
{
    printf ("In func\n");
    return 0;
}

int main (void)
{
    int *p = &arr[func()];
    if (p)
        printf("In main\n");
    return 0;
}

потом

$ gcc -Wall -Wextra -pedantic -std=gnu11 -Ofast -o bin/infunc infunc.c
$ ./bin/infunc
In func
In main

А сгенерированная сборка поддерживает другое поведение:

$ gcc -S -masm=intel -o infunc.asm infunc.c

$ cat infunc.asm
        .file   "infunc.c"
        .intel_syntax noprefix
        .text
        .comm   arr,40,32
        .section        .rodata
.LC0:
        .string "In func"
        .text
        .globl  func
        .type   func, @function
func:
.LFB0:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        lea     rdi, .LC0[rip]
        call    puts@PLT
        mov     eax, 0
        pop     rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   func, .-func
        .section        .rodata
.LC1:
        .string "In main"
        .text
        .globl  main
        .type   main, @function
main:
.LFB1:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        sub     rsp, 16
        mov     eax, 0
        call    func
        cdqe
        lea     rdx, 0[0+rax*4]
        lea     rax, arr[rip]
        add     rax, rdx
        mov     QWORD PTR -8[rbp], rax
        cmp     QWORD PTR -8[rbp], 0
        je      .L4
        lea     rdi, .LC1[rip]
        call    puts@PLT
.L4:
        mov     eax, 0
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE1:
        .size   main, .-main
        .ident  "GCC: (GNU) 7.3.0"
        .section        .note.GNU-stack,"",@progbits

Хотел бы я дать здесь какое-то логическое объяснение этой обработки, но я могу только задокументировать это. Кажется, нам нужно поговорить с парнями из списка gcc.


Побочные эффекты, отбрасываемые при вычислении адреса внутри if

Похоже, это регресс в gcc, который появится в зависимости от того, применяет ли отдельный дистрибутив достаточно исправлений, чтобы замаскировать его. Это ошибка gcc в работе. Ошибка 84607

Вы должны сообщить об ошибке в вашем дистрибутиве Linux. Кстати, в Debian / Sid я этого не наблюдаю.

Basile Starynkevitch 13.03.2018 07:25

Это также может объяснить некоторые недавние необъяснимые проблемы с дистрибутивом :(. Спасибо за ответ.

David C. Rankin 13.03.2018 07:26

Возможно, в вашем дистрибутиве есть какой-то странный файл спецификации, который требует некоторой оптимизации

Basile Starynkevitch 13.03.2018 07:27

Я думаю, что это просто регресс где-то в линейке вещей gcc на Arch. Сегодня в списке Arch (одна моя) есть пара необъяснимых ошибок, и все, что вызывает их, кажется идеальным кандидатом для устранения проблем. "Хьюстон у нас проблема..."

David C. Rankin 13.03.2018 07:28

Это ошибка gcc (# 84607), которая была исправлена ​​в gcc 7.3.1 или новее.

Кажется, это источник основной идеи цитаты кода в вопросе.

Yunnosch 13.03.2018 09:01

Другие вопросы по теме