LINUX.ORG.RU

static переменные в inline функциях

 


0

2

способен ли компилтор (гцц, шланг) осилить такое (тупо через создание глобальной переменной с соответствующей областью видимости)? или втихаря сделает ф-ию обычной? может, стандарт что-нибудь говорит?

★★★★★

Поясни, ты имеешь ввиду такой код?

inline void foo()
{
   static int value;
}
static переменная внутри функции тупо глобальная, видимая только внутри этой функции. Инлайнинг ничего не меняет, переменная по прежнему одна.

fluorite ★★★★★ ()
Ответ на: комментарий от fluorite

Вероятно он имеет ввиду примерно такой код:

#include <stdio.h>

inline int f1(void) {
  static int a;
  return a++;
}
int f2(void) { return f1(); }
int f3(void) { return f1(); }
int main() {
  printf("%i %i\n", f2(), f3());
  printf("%i %i\n", f2(), f3());
}

anonymous ()
Ответ на: комментарий от next_time

не думаю, по крайней мере поведение зависящее от флагов оптимизации - плохое поведение, а с -O0 он просто пропустит inline.

anonymous ()
Ответ на: комментарий от next_time

если хочешь, чтоб о тебе «хорошо» отзывались, тогда используй препроцессор:

#include <stdio.h>

#define f1() ({ \
  static int a; \
  a++; \
})
int f2(void) { return f1(); }
int f3(void) { return f1(); }
int main() {
  printf("%i %i\n", f2(), f3());
  printf("%i %i\n", f2(), f3());
}

anonymous ()
Ответ на: комментарий от next_time

еще раз, инлайн функция или нет, не влияет на то, где лежит static переменная, это либо секция .bss, либо .data твоего бинарника.

fluorite ★★★★★ ()

Почему нет?

И да, почему не попробовать?

emulek ()

Стандарт, емнип, гарантирует, что статическая переменная будет только одна, а вот будет ли функция реально подставлена или нет — это уж как компилятор решит

Gvidon ★★★★ ()

где тег "мне лень открыть стандарт"?

7.1.2.4 (с++11)

A static local variable in an extern inline function always refers to the same object.

anonymous ()
Ответ на: комментарий от emulek

в данном случае важен не порядок вычислений, а что статическая переменная одна, результат:

1 0
3 2
, а хотелось получить:
0 0
1 1

только я что-ли заметил: «static переменные»

anonymous ()
Ответ на: комментарий от fluorite

static переменные в inline функциях (комментарий)

мне интересно не состояние переменной, то, что, она по факту, станет глобальной — это очевидно, а состояние ф-ции, т.к. компилятор имеет право втихаря функцию разинлайнивать

next_time ★★★★★ ()
Ответ на: где тег "мне лень открыть стандарт"? от anonymous

вооо, спасибо. то есть, здесь есть указание разрешать инлайнить функции со статическими переменными внутри. но следуют ли ему, на сегодняшний день, компиляторы? гцц, шланг, другие?

next_time ★★★★★ ()
Последнее исправление: next_time (всего исправлений: 1)
Ответ на: комментарий от anonymous

у вас когнитивные расстройства, коллега

примеры: «решение уравнений третьей степени», «поведение обезьян_ перед зеркалом»...

anonymous ()
Ответ на: комментарий от next_time

Ну зафорсь инлайнинг, раз точно уверен, что тебе это нужно

always_inline
Generally, functions are not inlined unless optimization is specified. For functions declared inline, this attribute inlines the function even if no optimization level was specified.

https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Function-Attributes.html#Function-Attributes

fluorite ★★★★★ ()
Последнее исправление: fluorite (всего исправлений: 1)
Ответ на: комментарий от next_time

тогда надо добавить тег "мне лень запускать компилятор"

если вкратце:

-O0 — не инлайнит

-O1 — push rbp + jmp

-O2 — инлайнит именно так как ты хочешь

это шланг с внутренним связыванием.

anonymous ()
Ответ на: комментарий от anonymous

Ну как раз результат

1 0
3 2

И свидетельствует о том, что переменная одна...

А UB тут ибо мого быть и

0 1
2 3
на другой платформе, да и даже на той же самой...

Или ты какую то более глубокую мысль хочешь донести?

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Или ты какую то более глубокую мысль хочешь донести?

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

anonymous ()
Ответ на: комментарий от anonymous

С какого перепугу у тебя тут две переменные появятся?? Какое вообще отношение имеет переменная к коду? Абсолютно никакого, хоть она статическая, хоть глобальная, хоть какая.

emulek ()
Ответ на: комментарий от emulek

С какого перепугу у тебя тут две переменные появятся??

у вас когнитивные расстройства, коллега

я не верно понял начальную формулировку. обсуждение моей ошибки можно закрывать?

anonymous ()
Ответ на: комментарий от next_time

В моём коде инлайнило без проблем. Что тебя смущает? Код размножается, а переменная как лежала в секции данных, так и лежит.

emulek ()
Ответ на: комментарий от anonymous

Если в коде ub, то это не код, а говно, которое ничего не доказывает. Кстати, не удивлюсь, если компилятор сделает две переменные, имеет право, ибо ub.

emulek ()
Ответ на: комментарий от emulek

А, понял. Тс очевидно думал, что переменная в регистр заоптимизируется и далее будет тащится по коду.

Это не так. Статическая переменная всегда имеет своё место в памяти, где-то в стандарте про это было. Алсо нестатические инлайновые функции тоже имеют место быть, даже если только инлайняться. Компилятор ведь не знает, а вдруг кто-то захочет сделать указатель на функцию/метод?

emulek ()

ты сам этого попросил :(

#include <stdio.h>

inline int f1(int place) {
  #define sz 10;
  static int a[sz];
  static int t[sz]
  static int end=0;
  int i=0;
  a[end]=0;t[end]=place;
  while(t[i++]!=place);
  if(i>end)end=i; 
  return a[i-1]++;
}

#define ff() f1(_LINE_);
int f2(void) { return ff(); }
int f3(void) { return ff(); }
int main() {
  printf("%i %i\n", f2(), f3());
  printf("%i %i\n", f2(), f3());
}

т.е (реализация может и лучше) - ты по сути хочешь обьекты превазаные

qulinxao ★★☆ ()
Ответ на: комментарий от mashina

Разве, а я подумал, раз не специфицирован порядок выполнения функций с сайд эффектом по отношению к одному и тому же внешнему ресурсу, то это всё таки считается ub.

Но сути это не меняет - неконсистентность выходных данных никуда не пропадает, но в примере это и не важно :)

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

pon4ik ★★★★★ ()
Ответ на: комментарий от emulek

Тс очевидно думал, что переменная в регистр заоптимизируется и далее будет тащится по коду.

нет, так не думал

next_time ★★★★★ ()
Ответ на: комментарий от next_time

В сишке нет такого понятия. Есть только состояние статической переменной и состояние локальной переменной.

Функции неизменные, и у функций потому есть только одно состояние.

emulek ()
Ответ на: комментарий от emulek

если ТС'у нужно было независимые в разных функциях инлайновые статические то вот вариант.

по сути(если предположение верно) тс'у нужны области данных(статические) привязаные к инлайнингу .

qulinxao ★★☆ ()
Ответ на: комментарий от next_time

Как же ты думал-то? Inline это простое размножение кода, без учёта какого-то 'состояния'. Переменные к этому никакого отношения не имеют, имеют отношения разве что константы известные при компиляции. Компилятор может например выкинуть заголовок цикла, который выполняется один раз.

emulek ()
Ответ на: комментарий от qulinxao

Формально верно, но какой тогда срок от инлайна? Проще юзать локальные переменные в стеке. Это ещё и быстрее такого inline.

emulek ()
Ответ на: комментарий от emulek

в с++ есть понятие inline function. функция останется инлайн или нет, вот, что мне было интересно.

в результате выяснилось: шланг, и, гцц при -02 справляются, кроме того, в стандарте есть отсылка, что компилятор должен справляться с такими ситуациями.

next_time ★★★★★ ()
Ответ на: комментарий от emulek

Inline это простое размножение кода

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

next_time ★★★★★ ()
Ответ на: комментарий от next_time

На самом деле это на усмотрение компилятора. Да, справляются, но непонятно, чем мешают статические переменные?

emulek ()
Ответ на: комментарий от emulek

но непонятно, чем мешают статические переменные?

тем, что их тупой подстановкой подставить не выйдет. как решить проблему очевидно, но из этого напрямую ещё не следует, что она была везде решена, отсюда и вопрос.

next_time ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.