funkcja inline

Odpowiedz Nowy wątek
mir
2014-05-24 21:52
mir

Rejestracja: 11 lat temu

Ostatnio: 5 lat temu

0
#include "../require.h"
#include <iostream>
using namespace std;

template<class T>
class Array {
  enum { size = 100 };
  T A[size];
public:
  T& operator[](int index) {
    require(index >= 0 && index < size,
      "Index out of range");
    return A[index];
  }
};

int main() {
  Array<int> ia;
  Array<float> fa;
  for(int i = 0; i < 20; i++) {
    ia[i] = i * i;
    fa[i] = float(i) * 1.414;
  }
  for(int j = 0; j < 20; j++)
    cout << j << ": " << ia[j]
         << ", " << fa[j] << endl;
} ///:~

Z thinking in C++

Zwróć uwagę, że w przypadku gdy indeks jest niepoprawny do wydrukowania komunikatu jest używana funkcja require(). Ponieważ operator jest funkcja inline można używać takie sposobu w celu upewnienia się, że nie następuje naruszenie granic, a z gotowego kodu usunąć funkcję require()

1)
a)Dlaczego ten operator jest inline, a inne nie są, jaki jest tego powód?
b) w sumie, wyszło też drugie pytanie, niektóre spośród operatorów muszą być definiowane w klasie, a niektóre poza nią. Dlaczego? Czy ma to związek z tą inlinowosćią, np. opertora [].
2) Do cytatu:
Dlaczego inlinowość funkcji nam to umożliwia. Czegoś nie wiem? Ja na funkcje inline patrzę tak:
Jeżeli funkcje są małe i nie ma sensu skakać w inne miejsce w pamięci to użyj inline. To myślenie ma jakieś defekty?

edytowany 1x, ostatnio: mir, 2014-05-24 21:53

Pozostało 580 znaków

2014-05-24 21:58

Rejestracja: 15 lat temu

Ostatnio: 23 minuty temu

0

Po zinline'owaniu funkcji kompilator może odpalić swoje optymalizacje jeszcze raz, np usuwanie nadmiarowych ifów (w sensie np ty coś testujesz w miejscu wywołania operatora, a operator w środku testuje znów to samo). Funkcja która nie jest zinline'owana jest pewnego rodzaju black-boxem i kompilator nie jest w stanie wiele zrobić z wywołaniem.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

mir
2014-05-24 22:15
mir

Rejestracja: 11 lat temu

Ostatnio: 5 lat temu

0

ok. Czyli kompilator widząc przeciążanie [] sam go robi inline? Rozumiem, że jeżeli funkcja jest inline to kompilator nabiera śmiałości do optymalizacji. Tylko dlaczego?
Dobrze, ale dlaczego przeciążenie operatora [] jest akurat inline. Rozumiem, że ze względu na optymalizację. Ale jaką? Bo jest to przecież znane.

Pozostało 580 znaków

2014-05-24 22:21

Rejestracja: 15 lat temu

Ostatnio: 23 minuty temu

1

Generalnie, jeżeli nie używasz LTO to kompilator zinline'ować może tylko funkcje w aktualnej jednostce kompilacji (tzn plik .c/ .cpp + wszystkie dołączone pliki nagłówkowe). Wrzucając implementację operatora do deklaracji klasy sprawiasz, że ta implementacja jest widoczna wszędzie, a co za tym idzie zewsząd można ją zinline'ować.

Rozumiem, że jeżeli funkcja jest inline to kompilator nabiera śmiałości do optymalizacji. Tylko dlaczego?

Pfff. Śmiałości :P Nie chodzi o żadną śmiałość. Funkcja niezinline'owana jest w dużej mierze black-boxem - kompilatorowi dużo trudniej robić optymalizacje które przebijają się przez wywołania funkcji. Trudniej, bo przecież z tej niezinline'owanej funkcji można korzystać też z innych miejsc, więc ta funkcja musi zachować poprawność i przez to sprawdzać wszystkie niezmienniki zawarte w kodzie źródłowym.
Inline'ing to usunięcie wywołania funkcji, wklejenie ciała metody wywoływanej do funkcji wywołującej. Dzięki temu cały kod jest efektywnie w jednej funkcji, przez co łatwiej jest optymalizować, bo wklejone ciało funkcji jest niezależnym bytem.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

mir
2014-05-24 22:32
mir

Rejestracja: 11 lat temu

Ostatnio: 5 lat temu

0

dobrze. To mi wyjaśniłeś, ale dalej nie odpowiedziałeś, co operator [] ma w sobie takiego szczególnego?

Pozostało 580 znaków

2014-05-24 22:38

Rejestracja: 15 lat temu

Ostatnio: 23 minuty temu

1

A ma? Próbowałeś go definiować w osobnym pliku .c/ .cpp?

W sensie w definicji klasy zrób:

T& operator[](int index);

A w osobnym pliku .cpp zrób:

T& Array::operator[](int index) {
ciałolalalal;
}

Czy cóś w ten deseń.

Stawiam że ta inline'owość wynika tylko i wyłącznie z tego, że zdefiniowałeś operator w definicji klasy, a nie w osobnej jednostce komplacji.
Chociaż mogę się mylić, bo w C++ koduję tylko hobbystycznie i zgłębianie tego języka nie sprawia mi szczególnej przyjemności :P


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 3x, ostatnio: Wibowit, 2014-05-24 22:42

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0