Jak uniknąć wprowadzania redundantnych liczb w metodzie operującej na string?

0

W kodzie funkcji

void
E_main_I_help( Pc exe_name
){  N s_l = 7 + E_text_Z_s0_R_l( exe_name ) + 30 + 1;
    Pc s = M( s_l );
    if( !s )
    {   GV_(NA);
        return;
    }
    E_text_Z_s_P_copy_s0_0( E_text_Z_s_P_copy_s0( E_text_Z_s_P_copy_s0( s, "usage: " ), exe_name ), " [ -r ] [ root_path ... ]" );
    G_(); Gs0_(s);
    W(s);
}

są wykonywane następujące działania:

  1. Obliczenie rozmiaru docelowego bloku pamięci na tekst zakończony znakiem '\0'.
  2. Przydzielenie bloku pamięci na o tym rozmiarze.
  3. Skopiowanie wymaganych tekstów do tego bloku pamięci.
  4. Wypisanie tekstu.
  5. Zwolnienie wcześniej przydzielonego bloku pamięci.

Pytanie jest następujące: jak umożliwić kompilatorowi samodzielne obliczenie rozmiaru bloku pamięci na tekst?
Tak by było tylko jedno miejsce umieszczenia tekstów stałych oraz jedno miejsce przydzielenia bloku pamięci.

Pytanie dotyczy C, ale każdy pomysł w innym języku (jak np. C++) jest przydatny.
I nie należy się sugerować tutaj podanym przypadkiem, że tekst jest wypisywany, więc można by w C++ użyć format na standardowe wyjście. Tekst nie musi być wypisywany.

Pod koniec pisania tego ‘posta’ przypomniał mi się jeszcze sposób, jaki stosuję na przykład do obliczania rozmiaru bloku potrzebnego na tekst w funkcji formatującej tekst do postaci otoczonego znakami komentarza argumentu wiersza poleceń: dwie funkcje, jedna do obliczania rozmiaru bloku, druga do tworzenia tekstu w tym bloku.
Wtedy to wyglądałoby tak:

void
E_main_I_help( Pc exe_name
){  N s_l = E_text_Z_s_P_copy_s0_0_G( E_text_Z_s_P_copy_s0_G( E_text_Z_s_P_copy_s0_G( s, "usage: " ), exe_name ), " [ -r ] [ root_path ... ]" );
    Pc s = M( s_l );
    if( !s )
    {   GV_(NA);
        return;
    }
    E_text_Z_s_P_copy_s0_0( E_text_Z_s_P_copy_s0( E_text_Z_s_P_copy_s0( s, "usage: " ), exe_name ), " [ -r ] [ root_path ... ]" );
    G_(); Gs0_(s);
    W(s);
}

Ale wtedy muszę w dwóch miejscach podawać te same teksty.
A chodzi o zachowanie zwięzłości kodu.

1

Wielokrotne wystąpienie tego samego napisu kompilatory C optymalizują przynajmniej od 25 lat (w tej samej jednostce translacji - dam sobie rękę uciąć. Nowsze sądzę szerzej, współczesne MSVC coś robi)

Chyba była milion lat temu dyskusja - na co ci te koszmary ?
To chyba była jakaś premature optimalisation ?

1

Raczej chodzi o optymalny zapis kodu, a nie o to, czy kompilator znajdzie te same wystąpienia tekstu.

Tak by było tylko jedno miejsce umieszczenia tekstów stałych oraz jedno miejsce przydzielenia bloku pamięci.

1
overcq napisał(a):

Pytanie jest następujące: jak umożliwić kompilatorowi samodzielne obliczenie rozmiaru bloku pamięci na tekst?

#define USAGE_TEXT "usage: "
#define STRLEN(text) (sizeof(text) - 1)
const size_t usage_length = STRLEN(USAGE_TEXT);
overcq napisał(a):

Pytanie dotyczy C, ale każdy pomysł w innym języku (jak np. C++) jest przydatny.

constexpr std::string_view USAGE("usage: ");
constexpr size_t USAGE_LENGTH = USAGE.size();

Raczej chodzi o optymalny zapis kodu, a nie o to, czy kompilator znajdzie te same wystąpienia tekstu.

"Optymalny" zawiera w sobie "czytelny". To co wkleiles nie ma nic z tym wspolnego - inaczej nie trzeba by bylo tlumaczyc co ten kod robi.

0
overcq napisał(a):

Raczej chodzi o optymalny zapis kodu, a nie o to, czy kompilator znajdzie te same wystąpienia tekstu.

Tak by było tylko jedno miejsce umieszczenia tekstów stałych oraz jedno miejsce przydzielenia bloku pamięci.

Co to jest "optymalny zapis kodu" ? Bo to, co prezentujesz, to nie jest.
jeśli to jest, co zgaduję, to napisy możesz opakawac w #define (zero narzutu) lub const (zależnie od opcji / platformy możliwości / nowoczesności kompilatora)

Mi to pachnie jak jeden wielki XY problem.

0

Tłumaczyć trzeba tylko nazwy funkcji, ponieważ nie pochodzą z biblioteki standardowej, ale jeśli się je zna (ma pliki źródłowe), to nie trzeba nic tłumaczyć.

@eleventeen: W tym przypadku będę musiał umieścić dwukrotnie USAGE_TEXT: raz w obliczaniu rozmiaru, a drugi raz w kopiowaniu. Chociaż to i tak jest może lepsze rozwiązanie niż ‚gołe’ napisy, które jakkolwiek można łatwiej czytać.

0

@eleventeen: W tym przypadku będę musiał umieścić dwukrotnie USAGE_TEXT: raz w obliczaniu rozmiaru, a drugi raz w kopiowaniu.

W czym konkretnie przeszkadza uzywanie stalych w kodzie? W binarce bedzie jedno wystapienie. Wszelkie zmiany kodu beda w jednym miejscu. Jesli zrobisz literowke w nazwie stalej to kompilator to wylapie. Nie bardzo rozumiem czego innego oczekujesz jesli musisz przekazac parametry ktore od siebie zaleza do 2 roznych funkcji a jednoczesnie nie chcesz korzystac z tej samej stalej w kodzie.

0

Szczerze to nie wiem z czym problem, ze zrobieniem makra?

Jak masz długi ciąg nazw różnych zmiennych a potem chcesz mieć to też jako string albo cokolwiek to się używa sztuczki z X macro.

Przykładzik:

#include <stdio.h>

#define doX \
X( one ) \
X( two ) \
X( three )

#define X(x) int dig##x ;

struct num{
	
  doX
	
};

#undef X


#define X(x) #x,

char *arr[] = {
	
	doX
	NULL

};

#undef X

int main(void) {
	
	struct num num = { 1, 2, 3 };
	printf( "%d\n", num.digthree);
	puts( arr[1] );
	
	return 0;
}


0

Cały problem sprowadza się do konieczności uzyskania długości tekstów statycznych, ponieważ przeprowadzam zbyt wiele różnych operacji na tekstach niestatycznych, by można było to jakoś zuniwersalizować.
Dlatego na razie zdecydowałem się na użycie makra

#define J_s0_R_l(s) ( sizeof(s) - 1 )

tam, gdzie potrzeba zsumować długość tekstu statycznego.
I dwukrotny zapis tego samego tekstu statycznego, bez użycia zmiennych lub #define, ponieważ tak widać od razu, jaki tekst jest używany, a przynajmniej nie będzie błędów pamięci związanych z jego długością.

0

Borze, ale po co ?

Np strlen od wieków jest fajnie inlinowany, jest skrajnie przyjazny dla cache procesora itd...
C ma zmienne tablice VLA (de facto implementacje C++ też maja, choć standard tego nie określa)

Tłuczesz się z jakimiś pozornymi celami.

overcq napisał(a):

... ponieważ tak widać od razu ...

Fajnie się uśmiać w sobotę.
Nie, w tym projekcie niczego nie widać od razu

0

@Ridle, gratuluję kolejnej owocnej zmiany tematu

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