fout: lvalue vereist als unair & operand

Tijdens het compileren (met Linux Server versie 6.1)

strftime(AppTime, sizeof(AppTime),"%Y/%m/%d %T", localtime(&((long)u32_Time)));

foutmelding “error: lvalue required as unary ‘&’ operand”

maar dezelfde code is succesvol gecompileerd met Red Hat Enterprise Linux AS release 3.

Waarom zo? Hoe dit te corrigeren?


Antwoord 1, autoriteit 100%

De adres-operator &vereist een variabele om het adres van te nemen. Het resultaat van uw cast (long)u32_Timeis een tijdelijk resultaat dat niet noodzakelijkerwijs in het geheugen aanwezig is en daarom geen adres heeft dat kan worden ingenomen. Dus als dat stukje code ooit ergens is gecompileerd, was het een niet-standaard compiler-extensie.

De standaard, §5.3.1,3 vereist:

Het resultaat van de unaire & operator is een pointer naar zijn operand. De operand zal een waarde zijn […]

Hoe dit op te lossen:
std::localtimeverwacht een verwijzing naar een std::time_t, dus je kunt die het beste opgeven. Je hebt geen uitleg of verdere code gegeven, dus ik kan alleen maar raden dat u32_Timeeen niet-ondertekend rekenkundig type van 4 bytes is dat op de een of andere manier een tijd zou moeten vertegenwoordigen. Hoe dat correct wordt omgezet in een std::time_thangt af van hoe je compiler de laatste implementeert en hoe je de waarde van de verdere hebt gekregen. Gewoon een C-cast toepassen is nietoverdraagbaar, en casten naar longis nog minder overdraagbaar.
Als, en alleen alsde std::time_top uw huidige platformook een niet-ondertekend 32-bits type is met dezelfde weergave als uw u32_Time, het kan voldoende zijn om

. te gebruiken

localtime(reinterpret_cast<std::time_t*>(&u32_Time));

Overdraagbaarder zou zijn om de waarde eerst in het juiste gegevenstype op te slaan:

std::time_t time = u32_Time;
 localtime(&time);

Op die manier krijg je de nodige waarschuwingen en/of fouten als time_ten het type u32_Timeniet compatibel zijn.

Ik zou het gebruik van C-casts ten zeerste afraden, want als je dit stukje code eenmaal naar een ander platform moet porten, heb je geen middelen om die vervelende cast gemakkelijk te vinden.


Antwoord 2, autoriteit 32%

Het is waarschijnlijk het beste om te beginnen met wat de fout betekent. Een “lvalue” is iets dat aan de linkerkant van een isgelijkteken wordt weergegeven. Wat het betekent is dat uw argument voor de operator “adres van” (&) iets moet zijn dat u zou kunnen toewijzen. In jouw geval is dit syntactisch niet correct:

(long)u32_Time = 0;

De reden voor deze beperking is dat de & operator retourneert het adres van iets dat ergens is opgeslagen. (long)u32_Time wordt niet ergens opgeslagen, maar u32_Time wel.

Dit had misschien goed gewerkt op meer tolerante compilers omdat het wat ruimte zou toewijzen aan de lange representatie van u32_Time en je daar dan een verwijzing naar zou geven, maar ik zou er niet op rekenen dat het zou werken (zoals te zien is in Linux Server release 6.1).

Om dit op te lossen, kun je gewoon een nieuwe variabele maken en in plaats daarvan het adres nemen:

long long_Time = (long)u32_Time;
strftime(AppTime, sizeof(AppTime),"%Y/%m/%d %T", localtime(&long_Time));

Dat is echter nog steeds niet perfect. localtime verwacht een time_t-aanwijzer, geen lange aanwijzer, en hoewel ze op uw platform hetzelfde kunnen zijn, bent u beter af met:

time_t time_t_Time = (time_t)u32_Time;
strftime(AppTime, sizeof(AppTime),"%Y/%m/%d %T", localtime(&time_t_Time));

Other episodes