xor'ing αξία float & γενική ερώτηση καστ όσον αφορά την παραγωγή compiler

ψήφοι
0

Λοιπόν, οι δύο ερωτήματα ενδιαφερομένων για την κατάρτιση εξόδου μου, καθώς προσπαθώ να αφαιρέσετε όλες τις προειδοποιήσεις ..

Για το πρώτο ερώτημα :
Είμαι xor'ing τιμές float, έξοδος compiler: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

inline float ClassXY::GetFloat(void) const
{
    uint32_t xored = *(uint32_t*)&m_pParent->m_Value.m_fValue ^ (uint32_t)this; // compiler warning for this line
    return *(float*)&xored;
}

m_pParent είναι ένας δείκτης για αυτή την κατηγορία ClassXY *m_pParent;
m_Value είναι μια var ενός struct και m_fValue ορίζεται ως πλωτήρας μέσα στο struct.

Οποιαδήποτε ιδέα για το πώς να πάρει γύρω από την προειδοποίηση; (Ξέρω ότι μπορώ να απενεργοποιήσετε την προειδοποίηση, αλλά δεν έχω ιδέα για να πάρετε μια καθαρή λύση σε αυτό)

Μου δεύτερο qustion θα είναι:
Το σενάριο είναι σχεδόν το ίδιο όμως, μόνο με int. Compiler μιλάει για την απώλεια των πληροφοριών: warning: cast from ‘const ClassXY*’ to ‘uint32_t {aka unsigned int}’ loses precision [-fpermissive]
Χωρίς το -fpermissive σημαία compiler, δεν θα είναι σε θέση να συγκεντρώσει ..

inline int ClassXY::GetInt(void) const
{
    return (int)(m_pParent->m_Value.m_nValue ^ (int)this); // compiler warning for this line
}

Και πάλι, καμία ιδέα για το πώς να το διορθώσω αυτό;
Ή μήπως είναι inpossible χωρίς προειδοποίηση, αυτό που προσπαθώ να επιτύχει;

Για να σας δώσει όλες μια ιδέα περί τίνος πρόκειται: auto example = g_pClassXY->FindVar(example_var);
Τότε: float float_val = example->fValue; // direct access, value is wrong
Για να πάρετε τη σωστή τιμή, η σωστή προσέγγιση θα ήταν:float float_val = example->GetFloat();

Ευχαριστώ εκ των προτέρων!

Δημοσιεύθηκε 07/11/2018 στις 23:52
πηγή χρήστη
Σε άλλες γλώσσες...                            


1 απαντήσεις

ψήφοι
2

Για να αποφευχθεί μια αυστηρή παραβίαση aliasing, ο κώδικας θα μπορούσε να είναι:

static_assert( sizeof(float) <= sizeof(uint32_t), "size problem" );
uint32_t xored{};
memcpy(&xored, &m_pParent->m_Value.m_fValue, sizeof xored);
xored ^= reinterpret_cast<uint32_t>(this);

float ret;
memcpy(&ret, &xored, sizeof ret);
return ret;

Ωστόσο, υπάρχουν ακόμα μερικά ζητήματα:

  • Ο κωδικός είναι άρρωστος-σχηματίζεται σε ένα σύστημα όπου thisείναι ένας δείκτης 64-bit.
  • Οι τιμές float που εμπλέκονται μπορεί να είναι μια άκυρη μοτίβο bit για float, προκαλώντας απροσδιόριστη συμπεριφορά.

Εάν η πρόθεσή σας είναι να «κρυπτογράφηση» ένα float, τότε η κρυπτογραφημένη τιμή πρέπει να αποθηκεύονται όπως uint32_tή έναν πίνακα byte, δεν είναι τόσο float.

Το πρώτο σημείο θα μπορούσε να αντιμετωπιστεί με την παραγωγή ενός τυχαίου μάσκα 32-bit για κάθε εμφάνιση, αντί να χρησιμοποιεί this? ή με τη χρήση uintptr_tαντί του uint32_t.

Απαντήθηκε 08/11/2018 στις 00:17
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more