AMcoder - javascript, python, java, html, php, sql

Համապատասխանորեն հավասարեցրեք դատարկ ցուցիչը

gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

Ինչպե՞ս համապատասխանեցնել void * առանց հայտարարագրված տիպի հղում ունեցող միավորը քեշի տողի չափին համապատասխան ձևով:

Ինձ հետաքրքրում է ստանդարտի հետ հավասարեցման ընդհանուր տեխնիկայի օրինականությունը:

Իմ փորձը

void *ptr = //some valid pointer;
void *aligned_ptr = (void *) ((intptr_t) ptr & -64);

(intptr_t) ptr & -64 մասը համապատասխանում է, քանի որ ցանկացած 7.20.1.4 N2310:

անստորագիր ամբողջ տիպ, որն ունի այն հատկությունը, որ ցանկացած վավեր ցուցիչ void-ի կարող է փոխարկվել այս տեսակի, այնուհետև նորից ցուցիչի վերածվել void-ի, և արդյունքը կհամեմատվի սկզբնական ցուցիչի հետ:

(intptr_t) ptr & -64-ին void *-ի վերածելը հստակ սահմանված վարքագծի համար նախատեսված չէ: 6.3.2.3/5 տրամադրում է որոշ մշուշոտ տեղեկատվություն (օր. իմը).

Ամբողջ թիվը կարող է փոխարկվել ցանկացած ցուցիչի տեսակի: Բացառությամբ նախկինում նշվածի, արդյունքը սահմանված է իրականացման միջոցով, կարող է չլինի ճիշտ հավասարեցված, կարող է չմատնանշել կազմակերպության սուբյեկտին: հիշատակված տեսակ և կարող է լինել ծուղակի ներկայացում:

Եթե ​​ես ճիշտ եմ հասկանում «թակարդի ներկայացում» հասկացությունը, ապա նման դեպքում հնարավոր չէ ունենալ այն, քանի որ օբյեկտի տեսակը հայտարարված չէ։

Ես վստահ չեմ, արդյոք (void *) ((intptr_t) ptr & -64)-ը ճիշտ է դասավորված Ստանդարտ տեսակետից, թե արդյունքը սահմանված չէ:

UPD՝ 6.2.8 Նկարագրում է

Յուրաքանչյուր վավեր հավասարեցման արժեք պետք է լինի երկուսի ոչ բացասական ինտեգրալ ուժ:

Քանի որ _Alignof (max_align_t)_______________________________________________________________________________________________________________________________________________________________________________________________________ է, ուրեմն ես ենթադրում եմ, որ 64 բայթ հավասարեցումը պարտադիր չէ, որ ապահովվի gcc-ով:


  • Սա պատասխանո՞ւմ է ձեր հարցին: Ինչպես հավասարեցնել ցուցիչը C-ում 29.04.2020
  • @S.M. Իրականում ոչ: Ինձ հիմնականում հետաքրքրում է դրա հետևում գտնվող Ստանդարտի համապատասխանությունը, որը նախատեսված չէ ձեր նշած ՈԱ-ում: 29.04.2020
  • Ինչպես ասում է ստանդարտը, բացառությամբ ցուցիչից ամբողջ թվի և հետադարձի փոխարկումից, վարքագիծը սահմանված է իրականացման միջոցով: Քանի որ դուք օգտագործում եք GCC. Ցուցիչից ամբողջ թիվ փոխանցելիս և նորից, արդյունքում ստացված ցուցիչը պետք է հղում կատարի նույն օբյեկտին, ինչ սկզբնական ցուցիչը, հակառակ դեպքում վարքագիծը որոշված ​​չէ: Այսպիսով, եթե ձեր ցուցիչը արդեն հավասարեցված չէ քեշի գծին, ձեր կոդի վարքագիծը որոշված ​​չէ: 29.04.2020
  • բացառությամբ ցուցիչից ամբողջ թվի և հետադարձի փոխարկումից, վարքագիծը սահմանված է իրականացման միջոցով Վա՜յ: Շփոթված է C++ ստանդարտի հետ: C ստանդարտում նույնիսկ ամբողջ թվերի և հետադարձի փոխարկումները սահմանված են իրականացման միջոցով, բացառությամբ այն դեպքերի, երբ ցուցիչի արժեքը զրոյական է կամ ամբողջ թիվը զրո է: 29.04.2020
  • @LanguageLawyer Կարծես դա այն էր, ինչ ես ուզում էի: Հատկապես այն մասը Այսինքն՝ չի կարելի օգտագործել ամբողջ թվաբանություն՝ խուսափելու համար ցուցիչի թվաբանության անորոշ պահվածքից, ինչպես սահմանված է C99 և C11 6.5.6/8-ում 29.04.2020
  • Ինչ եք փորձում անել ձեր հատվածում անհասկանալի է: Ինչի՞ եք ուզում հասնել՝ կարգավորելով նման ցուցիչը: Եթե ​​այն չի մատնանշում վավեր օբյեկտ, ապա դա անիմաստ է: Սա XY խնդիր է թվում: Քեշի տողին ինչ-որ բան հավասարեցնելու ճիշտ ձևն այն է, որ այն պարզապես լրացված լինի անհրաժեշտ չափի մեջ՝ օգտագործելով __attribute__((aligned(64)) կամ նմանատիպ կոմպիլյատորների հրահանգները: Ավելորդ է ասել, որ սա չի կարող կատարվել ընդհանուր, ոչ կոմպիլյատորին հատուկ ձևով: Չկա որևէ ստանդարտով սահմանված միջոց՝ ինչ-որ բան քեշին համապատասխանեցնելու համար: 29.04.2020
  • @MarcoBonelli Կարծես դու ճիշտ ես: Հարցերից մեկն այն է, թե ինչու օգտագործեցիք gcc-հատուկ __attribute__ ստանդարտացված _Alignas-ի փոխարեն: 29.04.2020
  • «Եթե ես ճիշտ եմ հասկանում թակարդի ներկայացման հայեցակարգը, ապա նման դեպքում հնարավոր չէ ունենալ այն, քանի որ օբյեկտի տեսակը հայտարարված չէ»: void *-ի փոխակերպման արդյունքը կարող է լինել void * տեսակի թակարդի ներկայացում: 29.04.2020
  • @SomeName միայն այն պատճառով, որ այն C11 է, ես չէի ընտրի C11-ը միայն նման աննշան հատկության համար: Ես նաև ենթադրում էի, որ դուք խոսում եք C99-ի մասին, քանի որ դա ստանդարտի ամենատարածված տարբերակն է, որին պետք է հղում կատարել: 29.04.2020
  • @EricPostpischil Համաձայն եմ: Բայց եթե void * աղբյուրը չունի թակարդի ներկայացում, կարո՞ղ է արդյոք վերևում նկարագրված ձևով հավասարեցված ցուցիչը ունենալ թակարդի ներկայացում: 29.04.2020
  • @MarcoBonelli. Re «Այն, ինչ դուք փորձում եք անել ձեր հատվածում, անհասկանալի է: Ինչի՞ եք ուզում հասնել՝ նման ցուցիչը կարգավորելով»։ Նրանք ձգտում են գտնել քեշի գծի սկիզբը՝ կապված տվյալ հասցեի հետ: Սա սովորական տեխնիկա է կոդի համար, որն աշխատում է ապարատային մակարդակի մոտ: Օրինակ, բարձր արդյունավետության մատրիցային բազմապատկման ռեժիմը, հաշվի առնելով աղբյուրի և նպատակակետի հասցեները, կարող է տեղորոշել մոտակա քեշի գծերի սահմանները, որպեսզի աշխատանքը արդյունավետորեն բաժանվի քեշի երկրաչափության և հիշողության օգտագործման օրինաչափությունների վրա: 29.04.2020
  • @MarcoBonelli. Re «Քեշի տողին ինչ-որ բան հավասարեցնելու ճիշտ ձևն այն է, որ այն պարզապես լրացված լինի անհրաժեշտ չափի մեջ՝ օգտագործելով __attribute__((aligned(64)) կամ համանման կոմպիլյատորների դիրեկտիվները»:: Դա չէ, նպատակը. ոչ թե սահմանել/ստեղծել բարենպաստ դիրքով օբյեկտ, այլ գտնել քեշի գծի սահմանները գոյություն ունեցող օբյեկտի նկատմամբ: Նման բաները սովորական կարիք են բարձր արդյունավետությամբ գրադարաններում, որոնք պետք է սպասարկեն ցանկացած խնդրանք: 29.04.2020
  • @EricPostpischil, իրոք, մի քիչ հեռու է թվում, բայց ես ենթադրում եմ, որ դա հնարավոր սցենար կլիներ... 29.04.2020
  • @MarcoBonelli. Re «Սա կարծես XY խնդիր լինի»: սա սովորական աշխատանք է բարձր արդյունավետությամբ ծրագրային ապահովման մեջ: 29.04.2020
  • @MarcoBonelli. Re «մի քիչ հեռու է թվում իրոք». սա առօրյա է: Օրինակ՝ Apple-ի Accelerate շրջանակն ունի բազմաթիվ ձուլվածքներ դեպի uintptr_t և ետ՝ միջամտող մանիպուլյացիաներով: Հիմնականում դրա տեսակն է նախատեսված, որպեսզի ծրագրերը կարողանան աշխատել չմշակված ապարատային հասցեների հետ: 29.04.2020
  • Re “Ես վստահ չեմ, արդյոք (void *) ((intptr_t) ptr & -64)-ը ճիշտ է հավասարեցված Ստանդարտ տեսակետից, թե արդյունքը սահմանված չէ”: C ստանդարտը լռում է այդ արտահայտության արդյունքի հավասարեցման վերաբերյալ: Այդ կոդը համապատասխանում է (ընդունվում է C-ի որոշ համապատասխան կատարման կողմից), բայց խստորեն չի համապատասխանում (ամբողջովին սահմանված է C ստանդարտով): Այն կանի այն, ինչ ցանկանում եք C իրականացումներում, որոնք աջակցում են միջուկի կոդ կամ բարձր արդյունավետության կոդ գրելուն, քանի որ այդպիսի կոդի կարիքն ունի այս հատկանիշները, բայց դրա աջակցությունը պետք է երաշխավորված լինի C-ի ներդրմամբ, այլ ոչ թե C ստանդարտով: 29.04.2020

Պատասխանները:


1

Եթե ​​իսկապես ընդհանուր լուծում եք ուզում, միգուցե օգտագործեք union և ընտրովի որոշ նախապրոցեսորային մակրոներ:

union myptr{
    void *ptr;
    (whatever-type-that-meets-your-padding-requirment) padding;
};

union myptr myalignedptr;
#define alignedptr (myalignedptr.ptr)       /* optional */
30.04.2020
Նոր նյութեր

Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..