Thread: How to fix misaligned assignment statements in the source code?

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    19

    How to fix misaligned assignment statements in the source code?

    Hello All,

    I'm not a C/C++ programmer, but I'm familiar with this programm language.

    The thing is that I'm trying to compile and run DDS (Darwin Streaming Server) on "Gentoo on Sparc" architecture.

    Although I've managed to compile DSS under my arch. I'm constatntly get "Bus error" while trying to connect to DSS with QT player.

    I've read that:

    "The "bus error" signal usually means a data access was not properly aligned. It is always due to an error in the program.

    One major cause is accessing data via a pointer of a different type that has different alignment requirements. Example:

    Code:
    short s[2]; // 2-byte alignment
    
    int* p = (int*)s; // pretend the 2 shorts are one int int i = *p; // bus error is likely
    On SPARC, an int must be aligned on a 4-byte boundary, but a short only needs 2-byte alignment. The attempted load fails with a bus error if array s was not 4-byte aligned.

    Here is the example of resolution for this kind of problem on another project (a snap from the .diff):
    Code:
    @@ -499,8 +499,11 @@
             conn->request_len -= req->len;
             if (conn->request_len == 0)
                 break;
    -
    +#if defined (__i386__)
     req = (void *) req + req->len;
    +#else
    +memmove(&conn->request, (void *)req + req->len, conn->request_len); 
    +#endif
         }
     
         if (conn->request_len > 0 && req != &conn->request)
    So I thought there may be some way to overcome these alignment requirements by may be replacing (with some search and replace func.) int and short definitions with the proper ones?

    As I've said I'm not a C/C++ programmer so I hope you could give me some good advices to resolve this problem
    Last edited by biggyK; 05-26-2006 at 05:52 AM.

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The short answer is not to do tricks like casting a pointer to short into a pointer to int, as anything you do with that pointer to int subsequently yields undefined behaviour. If you want an int, declare it as an int. Or, to put it another way, find a way to write your program so you can make it compile without using a typecast (which is simply an instruction to the compiler not to complain when you do something potentially invalid).

    The most common basic reason for wanting to interpret an array of shorts as an int is that your program makes assumptions about relative sizes of types (eg in your case, you are assuming an int is twice the size of a short --- which is not true for all compilers). There are all sorts of reasons why you may wish to make that assumption (eg saving data in a binary format, which means both the program reading the file and the program writing the file must agree on precise layout of bits in characters, shorts, floats, data structures, etc) and eliminating such assumptions often requires basic design changes (eg defining a protocol and enforcing it in a PORTABLE manner).

    Incidentally, bus errors can result from other invalid operations on pointers (not just from issues with alignment). While the most common behaviour from invalid pointer operations (eg dereferencing a NULL, falling off the end of an array) is a core dump, a bus error is another possible result.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > Here is the example of resolution for this kind of problem on another project
    Here's an example of the blind leading the stupid more like.
    That's just ugly hackery, not a solution.

    > +#if defined (__i386__)
    > req = (void *) req + req->len;
    Two problems here
    1. Unaligned accesses are not unique to this architecture. Even where it is allowed, there may be a performance penalty (up to and including an exception trap to the OS).
    2. Arithmetic on void* is undefined - void has no size, therefore how can you add anything to it?
    Eg.
    foo.c:4: warning: pointer of type ‘void *’ used in arithmetic

    > +#else
    > +memmove(&conn->request, (void *)req + req->len, conn->request_len);
    1. But now the input data has been modified, which means something else later on in the code could be in for a big surprise.
    2. And the afore mentioned arithmetic on void*

    On the whole, fairly typical of the "works for me and my compiler" brigade.

    The best answer would have been to declare a new variable of the correct type, then memcpy() from the source to that variable. It always works and no messy conditional compilations, and no unexpected modifications of source data.

    > some good advices to resolve this problem
    Yes, fill out bug reports on the home site of that open source project pointing out the lack of portability of the code.
    Compile the code with debug symbols, run the code in a debugger and submit stack traces would probably be a good start.

    Oh yeah, and echo everything grumpy said as well.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    May 2006
    Posts
    19
    Thank you all for the answers,

    I've posted several questions on this problem to the developer list of DSS, but got no reply at all.
    Tried to find any active developer for this project but uselessly

    I've maked some changes to the source to make it recognize sparc64 arch., compiled but as I've said there is a "bus error" preventing me to use the programm.

    I've tried to debug the programm, using instructions I found on some 2001 year post to the list,
    with the below instructions:
    Code:
     root# ./gdbdar (or gdb ./DarwinStreamingServer -x gdb_script)
    
    Then, run the server like this: 
    
        (at the GDB prompt)
        r -d -S 5
    
    (which means -debug, stay attached to the session, and -S 5 means print status every 5 seconds)
    
    Now, connect your QT 5 client and see if the server crashes.  If so, then get a backtrace
    send it to use via the email to the Darwin Streaming Developers mailing list.
    
       (at the GDB prompt, after the crash occurs)
       bt
    I had to kill gdb process, cause it won't end:

    Code:
    # ./gdbdar
    GNU gdb 6.4
    Copyright 2005 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "sparc-unknown-linux-gnu"...Using host libthread_db l            ibrary "/lib/libthread_db.so.1".
    
    (gdb) r -d -S 5
    Starting program: /opt/dss8/DarwinStreamingSrvr5.5-Source/DarwinStreamingServer             -d -S 5
    [Thread debugging using libthread_db enabled]
    [New Thread 16384 (LWP 20477)]
    Below are my compilation warnings:

    Code:
    Below there are my compilation warnings (May be it willl help in some way to recognize the problem): 
    
    StrPtrLen.cpp: In member function `Bool16 StrPtrLen::NumEqualIgnoreCase(const char*, UInt32) const':
    StrPtrLen.cpp:143: warning: array subscript has type `char'
    StrPtrLen.cpp:143: warning: array subscript has type `char' 
    StrPtrLen.cpp: In member function `Bool16 StrPtrLen::EqualIgnoreCase(const char*, UInt32) const':
    StrPtrLen.cpp:156: warning: array subscript has type `char'
    StrPtrLen.cpp:156: warning: array subscript has type `char' 
    StrPtrLen.cpp: In member function `void StrPtrLen::PrintStr()':
    StrPtrLen.cpp:306: warning: array subscript has type `char'
    StrPtrLen.cpp: In member function `void StrPtrLen::PrintStrEOL(char*, char*)':
    StrPtrLen.cpp :336: warning: array subscript has type `char'
    UDPSocketPool.cpp: In member function `UDPSocketPair* UDPSocketPool::CreateUDPSocketPair(UInt32, UInt16)':
    UDPSocketPool.cpp:112: warning: comparison is always true due to limited range of data type In file included from SDPUtils.cpp:26:
    SDPUtils.h: In member function `Bool16 SDPContainer::HasLineType(char)':
    SDPUtils.h:92: warning: array subscript has type `char'
    SDPUtils.cpp: In member function `void SDPContainer::Parse()':
    SDPUtils.cpp:137: warning: array subscript has type `char'
    ar: creating libCommonUtilitiesLib.a
    ar: creating libQTFileLib.a
    ar: creating libQTFileExternalLib.a
    Server.tproj/QTSSDataConverter.cpp: In static member function `static QTSS_Error QTSSDataConverter::ConvertCHexStringToBytes(char*, void*, UInt32*)': 
    Server.tproj/QTSSDataConverter.cpp:270: warning: array subscript has type `char'
    Server.tproj/QTSSDataConverter.cpp:272: warning: array subscript has type `char'
    In file included from APICommonCode/SDPSourceInfo.cpp:40: 
    CommonUtilitiesLib/SDPUtils.h: In member function `Bool16 SDPContainer::HasLineType(char)':
    CommonUtilitiesLib/SDPUtils.h:92: warning: array subscript has type `char'
    In file included from APIModules/QTSSFileModule/QTSSFileModule.cpp:48: 
    CommonUtilitiesLib/SDPUtils.h: In member function `Bool16 SDPContainer::HasLineType(char)':
    CommonUtilitiesLib/SDPUtils.h:92: warning: array subscript has type `char'
    In file included from APIModules/QTSSReflectorModule/QTSSReflectorModule.cpp:59: 
    CommonUtilitiesLib/SDPUtils.h: In member function `Bool16 SDPContainer::HasLineType(char)':
    CommonUtilitiesLib/SDPUtils.h:92: warning: array subscript has type `char'
    APIModules/QTSSReflectorModule/QTSSReflectorModule.cpp: In function `void DoAnnounceAddRequiredSDPLines(QTSS_StandardRTSP_Params*, ResizeableStringFormatter*, char*)': 
    APIModules/QTSSReflectorModule/QTSSReflectorModule.cpp:847: warning: array subscript has type `char'
    In file included from APIModules/QTSSReflectorModule/RTSPSourceInfo.cpp:42:
    CommonUtilitiesLib/SDPUtils.h: In member function `Bool16 SDPContainer::HasLineType(char)': 
    CommonUtilitiesLib/SDPUtils.h:92: warning: array subscript has type `char'
    /usr/lib/gcc/sparc-unknown-linux-gnu/3.4.6/../../../../sparc-unknown-linux-gnu/bin/ld: warning: creating a DT_TEXTREL in object.
    /usr/lib/gcc/sparc-unknown-linux-gnu/3.4.6/../../../../sparc-unknown-linux-gnu/bin/ld: warning: creating a DT_TEXTREL in object. 
    /usr/lib/gcc/sparc-unknown-linux-gnu/3.4.6/../../../../sparc-unknown-linux-gnu/bin/ld: warning: creating a DT_TEXTREL in object.
    /usr/lib/gcc/sparc-unknown-linux-gnu/3.4.6/../../../../sparc-unknown-linux-gnu/bin/ld: warning: creating a DT_TEXTREL in object. 
    /usr/lib/gcc/sparc-unknown-linux-gnu/3.4.6/../../../../sparc-unknown-linux-gnu/bin/ld: warning: creating a DT_TEXTREL in object.
    proxy.c: In function `sig_catcher':
    proxy.c:177: warning: implicit declaration of function `sigignore' 
    QTSSPasswd.cpp:422: warning: 'char* SetTempPath(char*, int, char*, int, char)' defined but not used In file included from playlist_SDPGen.cpp:31:
    ../CommonUtilitiesLib/SDPUtils.h: In member function `Bool16 SDPContainer::HasLineType(char)': 
    ../CommonUtilitiesLib/SDPUtils.h:92: warning: array subscript has type `char'
    In file included from BroadcasterSession.cpp:38:
    ../CommonUtilitiesLib/SDPUtils.h: In member function `Bool16 SDPContainer::HasLineType(char)': 
    ../CommonUtilitiesLib/SDPUtils.h:92: warning: array subscript has type `char'
    It seems that I'm on my own with this problem, thats why I got here to this programmers forum.

    I'll give you any info on the source or compilation process for this programm if would kindly help me to solve this problem.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You should pay attention to some of those warnings, like these:
    Code:
    StrPtrLen.cpp:143: warning: array subscript has type `char'
    UDPSocketPool.cpp:112: warning: comparison is always true due to limited range of data type In file included from SDPUtils.cpp:26:
    It looks like you're using too many chars, in ways like
    Code:
    char c;
    if(c < 1000) array[c];
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > thats why I got here to this programmers forum
    But most forums like this are for helping newbies learn the language and fix problems with their own code.

    "I downloaded foo, but it doesn't work, please fix foo for me" posts like yours are considerably more time consuming to deal with. We can give general advice on what to look for, or what to try next but the bulk of the effort is going to have to be yours.

    > I'm not a C/C++ programmer, but I'm familiar with this programm language.
    Familiar enough to make changes to the code ?

    Here are a few steps you can take
    1. If you know about cvs or sccs or rcs, then I would suggest you start using it by putting a clean copy of this project into it. Keeping track of changes is going to be important.
    At the very least, have directories which contains all the code "as downloaded" and then all the code "as edited".

    2. Fix warnings as you find them - all those "char as subscript" are simply horrible in something which alludes to being something to do with strings.

    3. The next step would be to compile the code with this flag, and look closely at anything it flags up
    Code:
    `-Wcast-align'
         Warn whenever a pointer is cast such that the required alignment
         of the target is increased.  For example, warn if a `char *' is
         cast to an `int *' on machines where integers can only be accessed
         at two- or four-byte boundaries.
    Anything doing this is capable of (though not guaranteed to) drawing a bus error.

    > proxy.c: In function `sig_catcher':
    Check whether anything is catching / ignoring SIGBUS, or any other fatal signals. Doing so may interfere with your ability to debug the program. Maybe fine when the server is in use, but you want to make it useful for debugging.
    Likewise, are there any calls to daemon() or fork() in the code. You could be debugging the wrong process if you're not careful.

    I found this link on DT_TEXTREL
    http://www.codecomments.com/archive2...-6-517685.html
    Try pasting error messages into google in the first instance if you're stuck.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    May 2006
    Posts
    19
    Hello,

    Thanks for all the responses here.

    The -fPIC compiler flag indeed removes DT_TEXTREL... warnings

    I've started with adding `-Wcast-align' to the compiler options,
    and got a lot of these warnings (it's just a little snap):
    Code:
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `UInt32 ReflectorPacket::GetSSRC(Bool16)':
    APIModules/QTSSReflectorModule/ReflectorStream.h:120: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `UInt32 ReflectorPacket::GetPacketRTPTime()':
    APIModules/QTSSReflectorModule/ReflectorStream.h:139: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h:145: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `UInt16 ReflectorPacket::GetPacketRTPSeqNum()':
    APIModules/QTSSReflectorModule/ReflectorStream.h:157: warning: cast from `char*' to `UInt16*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `SInt64 ReflectorPacket::GetPacketNTPTime()':
    APIModules/QTSSReflectorModule/ReflectorStream.h:168: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    In file included from APIModules/QTSSReflectorModule/RTSPSourceInfo.cpp:42:
    CommonUtilitiesLib/SDPUtils.h: In member function `Bool16 SDPContainer::HasLineType(char)':
    CommonUtilitiesLib/SDPUtils.h:92: warning: array subscript has type `char'
    In file included from APIModules/QTSSReflectorModule/ReflectorStream.h:55,
                     from APIModules/QTSSReflectorModule/ReflectorSession.h:45,
                     from APIModules/QTSSReflectorModule/RelaySession.h:35,
                     from APIModules/QTSSReflectorModule/RelayOutput.h:37,
                     from APIModules/QTSSReflectorModule/RelayOutput.cpp:34:
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetSSRC(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:112: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h:115: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h:119: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h:123: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetClientSSRC(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:130: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetNTPTimestamp(SInt64)':
    RTCPUtilitiesLib/RTCPSRPacket.h:136: warning: cast from `char (*)[132]' to `SInt64*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetRTPTimestamp(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:145: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetPacketCount(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:150: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetByteCount(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:155: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetAckTimeout(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:160: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    In file included from APIModules/QTSSReflectorModule/ReflectorSession.h:45,
                     from APIModules/QTSSReflectorModule/RelaySession.h:35,
                     from APIModules/QTSSReflectorModule/RelayOutput.h:37,
                     from APIModules/QTSSReflectorModule/RelayOutput.cpp:34:
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `UInt32 ReflectorPacket::GetSSRC(Bool16)':
    APIModules/QTSSReflectorModule/ReflectorStream.h:120: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `UInt32 ReflectorPacket::GetPacketRTPTime()':
    APIModules/QTSSReflectorModule/ReflectorStream.h:139: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h:145: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `UInt16 ReflectorPacket::GetPacketRTPSeqNum()':
    APIModules/QTSSReflectorModule/ReflectorStream.h:157: warning: cast from `char*' to `UInt16*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `SInt64 ReflectorPacket::GetPacketNTPTime()':
    APIModules/QTSSReflectorModule/ReflectorStream.h:168: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    In file included from APIModules/QTSSReflectorModule/ReflectorStream.h:55,
                     from APIModules/QTSSReflectorModule/ReflectorSession.h:45,
                     from APIModules/QTSSReflectorModule/RTPSessionOutput.h:40,
                     from APIModules/QTSSReflectorModule/RTPSessionOutput.cpp:34:
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetSSRC(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:112: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h:115: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h:119: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h:123: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetClientSSRC(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:130: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetNTPTimestamp(SInt64)':
    RTCPUtilitiesLib/RTCPSRPacket.h:136: warning: cast from `char (*)[132]' to `SInt64*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetRTPTimestamp(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:145: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetPacketCount(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:150: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetByteCount(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:155: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    RTCPUtilitiesLib/RTCPSRPacket.h: In member function `void RTCPSRPacket::SetAckTimeout(UInt32)':
    RTCPUtilitiesLib/RTCPSRPacket.h:160: warning: cast from `char (*)[132]' to `UInt32*' increases required alignment of target type
    In file included from APIModules/QTSSReflectorModule/ReflectorSession.h:45,
                     from APIModules/QTSSReflectorModule/RTPSessionOutput.h:40,
                     from APIModules/QTSSReflectorModule/RTPSessionOutput.cpp:34:
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `UInt32 ReflectorPacket::GetSSRC(Bool16)':
    APIModules/QTSSReflectorModule/ReflectorStream.h:120: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `UInt32 ReflectorPacket::GetPacketRTPTime()':
    APIModules/QTSSReflectorModule/ReflectorStream.h:139: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h:145: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `UInt16 ReflectorPacket::GetPacketRTPSeqNum()':
    APIModules/QTSSReflectorModule/ReflectorStream.h:157: warning: cast from `char*' to `UInt16*' increases required alignment of target type
    APIModules/QTSSReflectorModule/ReflectorStream.h: In member function `SInt64 ReflectorPacket::GetPacketNTPTime()':
    APIModules/QTSSReflectorModule/ReflectorStream.h:168: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSReflectorModule/RTPSessionOutput.cpp: In member function `QTSS_Error RTPSessionOutput::RewriteRTCP(void**, StrPtrLen*, SInt64*, UInt32, SInt64*, SInt64*, UInt64*, SInt64*)':
    APIModules/QTSSReflectorModule/RTPSessionOutput.cpp:399: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSReflectorModule/RTPSessionOutput.cpp:401: warning: cast from `UInt32*' to `SInt64*' increases required alignment of target type
    APIModules/QTSSReflectorModule/RTPSessionOutput.cpp: In member function `UInt16 RTPSessionOutput::GetPacketSeqNumber(StrPtrLen*)':
    APIModules/QTSSReflectorModule/RTPSessionOutput.cpp:622: warning: cast from `char*' to `UInt16*' increases required alignment of target type
    APIModules/QTSSReflectorModule/RTPSessionOutput.cpp: In member function `void RTPSessionOutput::SetPacketSeqNumber(StrPtrLen*, UInt16)':
    APIModules/QTSSReflectorModule/RTPSessionOutput.cpp:632: warning: cast from `char*' to `UInt16*' increases required alignment of target type
    APIModules/QTSSWebStatsModule/QTSSWebStatsModule.cpp: In function `void SendStats(void*, UInt32, Bool16, StrPtrLen*)':
    APIModules/QTSSWebStatsModule/QTSSWebStatsModule.cpp:650: warning: cast from `char*' to `UInt16*' increases required alignment of target type
    APIModules/QTSSAdminModule/AdminElementNode.cpp: In member function `void ElementNode::SetElementDataPtr(SInt32, char*, Bool16)':
    APIModules/QTSSAdminModule/AdminElementNode.cpp:639: warning: cast from `char*' to `ElementNode*' increases required alignment of target type
    APIModules/QTSSAdminModule/AdminElementNode.cpp: In member function `virtual void ElementNode::SetUpSingleNode(QueryURI*, StrPtrLen*, StrPtrLen*, SInt32, QTSS_Initialize_Params*)':
    APIModules/QTSSAdminModule/AdminElementNode.cpp:714: warning: cast from `char*' to `ElementNode*' increases required alignment of target type
    APIModules/QTSSAdminModule/AdminElementNode.cpp: In member function `void ElementNode::RespondWithSingleElement(void*, QueryURI*, StrPtrLen*)':
    APIModules/QTSSAdminModule/AdminElementNode.cpp:1844: warning: cast from `char*' to `ElementNode*' increases required alignment of target type
    APIModules/QTSSAdminModule/AdminElementNode.cpp: In member function `void ElementNode::RespondWithAllElements(void*, QueryURI*, StrPtrLen*)':
    APIModules/QTSSAdminModule/AdminElementNode.cpp:1942: warning: cast from `char*' to `ElementNode*' increases required alignment of target type
    APIModules/QTSSAdminModule/AdminElementNode.cpp: In member function `void ElementNode::RespondWithAllNodes(void*, QueryURI*, StrPtrLen*)':
    APIModules/QTSSAdminModule/AdminElementNode.cpp:1990: warning: cast from `char*' to `ElementNode*' increases required alignment of target type
    APIModules/QTSSMP3StreamingModule/QTSSMP3StreamingModule.cpp: In function `QTSS_Error SessionClosing(QTSS_RTSPSession_Params*)':
    APIModules/QTSSMP3StreamingModule/QTSSMP3StreamingModule.cpp:1927: warning: cast from `MP3Session*' to `MP3ClientSession*' increases required alignment of target type
    APIModules/QTSSMP3StreamingModule/QTSSMP3StreamingModule.cpp: In function `QTSS_Error ReEnterFilterRequest(QTSS_Filter_Params*, MP3Session*)':
    APIModules/QTSSMP3StreamingModule/QTSSMP3StreamingModule.cpp:2704: warning: cast from `MP3Session*' to `MP3ClientSession*' increases required alignment of target type
    APIModules/QTSSRTPFileModule/RTPFileSession.cpp: In member function `RTPFileSession::ErrorCode RTPFileSession::Seek(Float64)':
    APIModules/QTSSRTPFileModule/RTPFileSession.cpp:216: warning: cast from `UInt8*' to `RTPFilePacket*' increases required alignment of target type
    APIModules/QTSSRTPFileModule/RTPFileSession.cpp:228: warning: cast from `UInt8*' to `UInt16*' increases required alignment of target type
    APIModules/QTSSRTPFileModule/RTPFileSession.cpp:229: warning: cast from `UInt8*' to `UInt32*' increases required alignment of target type
    APIModules/QTSSRTPFileModule/RTPFileSession.cpp: In member function `Float64 RTPFileSession::GetNextPacket(UInt8**, UInt32*, void**)':
    APIModules/QTSSRTPFileModule/RTPFileSession.cpp:309: warning: cast from `UInt8*' to `RTPFilePacket*' increases required alignment of target type
    APIModules/QTSSRTPFileModule/RTPFileSession.cpp:347: warning: cast from `UInt8*' to `UInt32*' increases required alignment of target type
    Doing a little research on the net I've found
    "QuickTime Streaming Server Modules - Programming Guide"
    with -
    Code:
    Naming Conventions:
    The QTSS programming interface uses a naming convention for the data types that it defines. The
    convention is to use the size of the data type in the name. Here are the data types that the QTSS
    programming interface uses:
    ■ Bool16— A 16-bit Boolean value
    ■ SInt64— A signed 64-bit integer value
    ■ SInt32— A signed 32-bit integer value
    ■ UInt16— An unsigned 16-bit integer value
    ■ UInt32— An unsigned 32-bit integer value
    Parameters for callback functions defined by the QTSS programming interface follow these naming
    conventions:
    ■ Input parameters begin with in.
    ■ Output parameters begin with out.
    ■ Parameters that are used for both input and output begin with io.
    
    Data Types:
    Data types can be any server-allowed text value. New data types can be defined and returned by the
    server, so data types are not limited to the basic set listed here:
    UInt8 SInt16 UInt64 Float64 char
    SInt8 UInt32 SInt64 Bool8 QTSS_Object
    UInt16 SInt32 Float32 Bool16 void_pointer
    Values of type QTSS_Object, pointers, and unknown data types always converted to a host-ordered
    string of hexadecimal values. Here is an example of a hexadecimal value result:
    unknown_pointer=halogen; type=void_pointer
    May be one possible solution is to replace all UInt16 to UInt32?

    But what to do in the case of "cast from `char*' to `UInt16*'" or `char*' to `UInt32*' or `char*' to `short unsigned int*'?

    Code:
    playlist_elements.cpp: In member function `SInt16 RTpPacket::GetHeaderInfo(UInt32*, UInt16*, UInt32*, unsigned char*)':
    playlist_elements.cpp:825: warning: cast from `char*' to `UInt16*' increases required alignment of target type
    playlist_elements.cpp:826: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    playlist_elements.cpp: In member function `SInt16 RTpPacket::SetHeaderInfo(UInt32, UInt16, UInt32, unsigned char)':
    playlist_elements.cpp:847: warning: cast from `char*' to `UInt16*' increases required alignment of target type
    playlist_elements.cpp:848: warning: cast from `char*' to `UInt32*' increases required alignment of target type
    Any Suggestions?
    Last edited by biggyK; 05-28-2006 at 04:31 AM.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Wow, all that code in header files is sure bloating your executables.

    > But what to do in the case of "cast from `char*' to `UInt16*'" or `char*' to `UInt32*' or `char*' to `short unsigned int*'?
    I explained already - declare a variable of the right type, then do a memcpy()
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    May 2006
    Posts
    19
    Hi,

    Sorry, but I need some practical example (As I've said I'm not as good with C/C++ as I would like).

    Lets say I got these warnings:
    Code:
    SocketUtils.cpp: In static member function `static void SocketUtils::Initialize(Bool16)':
    SocketUtils.cpp:375: warning: cast from `char*' to `ifreq*' increases required alignment of target type
    SocketUtils.cpp:422: warning: cast from `UInt8*' to `SocketUtils::IPAddrInfo*' increases required alignment of target type
    SocketUtils.cpp:472: warning: cast from `char*' to `ifreq*' increases required alignment of target type
    SocketUtils.cpp:482: warning: cast from `sockaddr*' to `sockaddr_in*' increases required alignment of target type
    And SocketUtils.cpp looks like this:
    Code:
         26     File:       SocketUtils.cpp
         27
         28     Contains:   Implements utility functions defined in SocketUtils.h
         29
         30
         31
         32
         33 */
         34
         35 #include <string.h>
         36
         37 #ifndef __Win32__
         38 #include <sys/types.h>
         39 #include <sys/socket.h>
         40 #include <netinet/in.h>
         41 #include <arpa/inet.h>
         42 #include <netdb.h>
         43 #include <sys/ioctl.h>
         44
         45 #if __FreeBSD__
         46 #include <ifaddrs.h>
         47 #endif
         48 #include <unistd.h>
         49 #include <sys/utsname.h>
         50
         51 #if __solaris__
         52 #include <sys/sockio.h>
         53 #endif
         54 #endif
         55
         56 #include "SocketUtils.h"
         57
         58 #ifdef SIOCGIFNUM
         59 #define USE_SIOCGIFNUM 1
         60 #endif
         61
         62 #ifdef TRUCLUSTER  /* Tru64 Cluster Alias support */
         63
         64 #include <clua/clua.h>
         65 #include <sys/clu.h>
         66
         67 static clua_status_t (*clua_getaliasaddress_vector) (struct sockaddr *, int *);
         68 static char *(*clua_error_vector) (clua_status_t);
         69
         70 #define clua_getaliasaddress (*clua_getaliasaddress_vector)
         71 #define clua_error (*clua_error_vector)
         72
         73 struct clucall_vector clua_vectors[] = {
         74         { "clua_getaliasaddress", &clua_getaliasaddress_vector },
         75         { "clua_error", &clua_error_vector },
         76         { NULL,     NULL }              /* END OF LIST */
         77 };
         78
         79 #endif /* TRUCLUSTER */
         80
         81 UInt32                          SocketUtils::sNumIPAddrs = 0;
         82 SocketUtils::IPAddrInfo*        SocketUtils::sIPAddrInfoArray = NULL;
         83 OSMutex SocketUtils::sMutex;
         84
         85 #if __FreeBSD__
         86
         87 //Complete rewrite for FreeBSD.
         88 //The non-FreeBSD version really needs to be rewritten - it's a bit of a mess...
         89 void SocketUtils::Initialize(Bool16 lookupDNSName)
         90 {
         91     struct ifaddrs* ifap;
         92     struct ifaddrs* currentifap;
         93     struct sockaddr_in* sockaddr;
         94     int result = 0;
         95
         96     result = getifaddrs(&ifap);
         97
         98     //Count them first
         99     currentifap = ifap;
        100     while( currentifap != NULL )
        101     {
        102         sockaddr = (struct sockaddr_in*)currentifap->ifa_addr;
        103         if (sockaddr->sin_family == AF_INET)
        104             sNumIPAddrs++;
        105         currentifap = currentifap->ifa_next;
        106     }
        107
        108
        109     //allocate the IPAddrInfo array. Unfortunately we can't allocate this
        110     //array the proper way due to a GCC bug
        111     UInt8* addrInfoMem = new UInt8[sizeof(IPAddrInfo) * sNumIPAddrs];
        112     ::memset(addrInfoMem, 0, sizeof(IPAddrInfo) * sNumIPAddrs);
        113     sIPAddrInfoArray = (IPAddrInfo*)addrInfoMem;
        114
        115     int addrArrayIndex = 0;
        116     currentifap = ifap;
        117     while( currentifap != NULL )
        118     {
        119         sockaddr = (struct sockaddr_in*)currentifap->ifa_addr;
        120
        121         if (sockaddr->sin_family == AF_INET)
        122         {
        123             char* theAddrStr = ::inet_ntoa(sockaddr->sin_addr);
        124
        125             //store the IP addr
        126             sIPAddrInfoArray[addrArrayIndex].fIPAddr = ntohl(sockaddr->sin_addr.s_addr);
        127
        128             //store the IP addr as a string
        129             sIPAddrInfoArray[addrArrayIndex].fIPAddrStr.Len = ::strlen(theAddrStr);
        130             sIPAddrInfoArray[addrArrayIndex].fIPAddrStr.Ptr = new char[sIPAddrInfoArray[addrArrayIndex].fIPAddrStr.Le        n + 2];
        131             ::strcpy(sIPAddrInfoArray[addrArrayIndex].fIPAddrStr.Ptr, theAddrStr);
        132
        133             struct hostent* theDNSName = NULL;
        134             if (lookupDNSName) //convert this addr to a dns name, and store it
        135             {   theDNSName = ::gethostbyaddr((char *)&sockaddr->sin_addr, sizeof(sockaddr->sin_addr), AF_INET);
        136             }
        137
        138             if (theDNSName != NULL)
        139             {
        140                 sIPAddrInfoArray[addrArrayIndex].fDNSNameStr.Len = ::strlen(theDNSName->h_name);
        141                 sIPAddrInfoArray[addrArrayIndex].fDNSNameStr.Ptr = new char[sIPAddrInfoArray[addrArrayIndex].fDNSName        Str.Len + 2];
        142                 ::strcpy(sIPAddrInfoArray[addrArrayIndex].fDNSNameStr.Ptr, theDNSName->h_name);
        143             }
        144             else
        145             {
        146                 //if we failed to look up the DNS name, just store the IP addr as a string
        147                 sIPAddrInfoArray[addrArrayIndex].fDNSNameStr.Len = sIPAddrInfoArray[addrArrayIndex].fIPAddrStr.Len;
        148                 sIPAddrInfoArray[addrArrayIndex].fDNSNameStr.Ptr = new char[sIPAddrInfoArray[addrArrayIndex].fDNSName        Str.Len + 2];
        149                 ::strcpy(sIPAddrInfoArray[addrArrayIndex].fDNSNameStr.Ptr, sIPAddrInfoArray[addrArrayIndex].fIPAddrSt        r.Ptr);
        150             }
        151
        152             addrArrayIndex++;
        153         }
        154
        155         currentifap = currentifap->ifa_next;
        156     }
        157
        158
        159 }
        160
        161 #else //__FreeBSD__
        162
        163 //Version for all non-FreeBSD platforms.
        164
        165 void SocketUtils::Initialize(Bool16 lookupDNSName)
        166 {
        167 #if defined(__Win32__) || defined(USE_SIOCGIFNUM)
        168
        169     int tempSocket = ::socket(AF_INET, SOCK_DGRAM, 0);
        170     if (tempSocket == -1)
        171         return;
        172
        173 #ifdef __Win32__
        174
        175     static const UInt32 kMaxAddrBufferSize = 2048;
        176     char inBuffer[kMaxAddrBufferSize];
        177     char outBuffer[kMaxAddrBufferSize];
        178     UInt32 theReturnedSize = 0;
        179
        180     //
        181     // Use the WSAIoctl function call to get a list of IP addresses
        182     int theErr = ::WSAIoctl(    tempSocket, SIO_GET_INTERFACE_LIST,
        183                                 inBuffer, kMaxAddrBufferSize,
        184                                 outBuffer, kMaxAddrBufferSize,
        185                                 &theReturnedSize,
        186                                 NULL,
        187                                 NULL);
        188     Assert(theErr == 0);
        189     if (theErr != 0)
        190         return;
        191
        192     Assert((theReturnedSize % sizeof(INTERFACE_INFO)) == 0);
        193     LPINTERFACE_INFO addrListP = (LPINTERFACE_INFO)&outBuffer[0];
        194
        195     sNumIPAddrs = theReturnedSize / sizeof(INTERFACE_INFO);
        196 #else
        197 #if defined(USE_SIOCGIFNUM)
        198     if (::ioctl(tempSocket, SIOCGIFNUM, (char*)&sNumIPAddrs) == -1)
        199     {
        200 #ifdef MAXIFS
        201         sNumIPAddrs = MAXIFS;
        202 #else
        203         sNumIPAddrs = 64;
        204 #endif
        205     }
        206 #else
        207 #error
        208 #endif
        209     struct ifconf ifc;
        210     ::memset(&ifc,0,sizeof(ifc));
        211     ifc.ifc_len = sNumIPAddrs * sizeof(struct ifreq);
        212     ifc.ifc_buf = (caddr_t)new struct ifreq[sNumIPAddrs];
        213     Assert(ifc.ifc_buf != NULL);
        214
        215     ::memset(ifc.ifc_buf, '\0', ifc.ifc_len);
        216     int theErr = ::ioctl(tempSocket, SIOCGIFCONF, (char*)&ifc);
        217     Assert(theErr == 0);
        218     if (theErr != 0)
        219         return;
        220     struct ifreq* ifr = (struct ifreq*)ifc.ifc_buf;
        221 #endif
        222
        223     //allocate the IPAddrInfo array. Unfortunately we can't allocate this
        224     //array the proper way due to a GCC bug
        225     UInt8* addrInfoMem = new UInt8[sizeof(IPAddrInfo) * sNumIPAddrs];
        226     ::memset(addrInfoMem, 0, sizeof(IPAddrInfo) * sNumIPAddrs);
        227     sIPAddrInfoArray = (IPAddrInfo*)addrInfoMem;
        228
        229     //for (UInt32 addrCount = 0; addrCount < sNumIPAddrs; addrCount++)
        230     UInt32 currentIndex = 0;
        231     for (UInt32 theIfCount = sNumIPAddrs, addrCount = 0;
        232          addrCount < theIfCount; addrCount++)
        233     {
        234 #ifdef __Win32__
        235         // We *should* count the loopback interface as a valid interface.
        236         //if (addrListP[addrCount].iiFlags & IFF_LOOPBACK)
        237         //{
        238             // Don't count loopback addrs
        239         //  sNumIPAddrs--;
        240         //  continue;
        241         //}
        242         //if (addrListP[addrCount].iiFlags & IFF_LOOPBACK)
        243         //  if (lookupDNSName) // The playlist broadcaster doesn't care
        244         //      Assert(addrCount > 0); // If the loopback interface is interface 0, we've got problems
        245
        246         struct sockaddr_in* theAddr = (struct sockaddr_in*)&addrListP[addrCount].iiAddress;
        247 #elif defined(USE_SIOCGIFNUM)
        248         if (ifr[addrCount].ifr_addr.sa_family != AF_INET)
        249         {
        250             sNumIPAddrs--;
        251             continue;
        252         }
        253         struct ifreq ifrf;
        254         ::memset(&ifrf,0,sizeof(ifrf));
        255         ::strncpy(ifrf.ifr_name, ifr[addrCount].ifr_name, sizeof(ifrf.ifr_name));
        256         theErr = ::ioctl(tempSocket, SIOCGIFFLAGS, (char *) &ifrf);
        257         Assert(theErr != -1);
        258
        259 #ifndef __solaris__
        260         /* Skip things which aren't interesting */
        261         if ((ifrf.ifr_flags & IFF_UP) == 0 ||
        262             (ifrf.ifr_flags & (IFF_BROADCAST | IFF_POINTOPOINT)) == 0)
        263         {
        264             sNumIPAddrs--;
        265             continue;
        266         }
        267         if (ifrf.ifr_flags & IFF_LOOPBACK)
        268         {
        269             Assert(addrCount > 0); // If the loopback interface is interface 0, we've got problems
        270         }
        271 #endif
        272
        273         struct sockaddr_in* theAddr = (struct sockaddr_in*)&ifr[addrCount].ifr_addr;
        274     #if 0
        275         puts(ifr[addrCount].ifr_name);
        276     #endif
        277 #else
        278 #error
        279 #endif
        280
        281         char* theAddrStr = ::inet_ntoa(theAddr->sin_addr);
        282
        283         //store the IP addr
        284         sIPAddrInfoArray[currentIndex].fIPAddr = ntohl(theAddr->sin_addr.s_addr);
        285
        286         //store the IP addr as a string
        287         sIPAddrInfoArray[currentIndex].fIPAddrStr.Len = ::strlen(theAddrStr);
        288         sIPAddrInfoArray[currentIndex].fIPAddrStr.Ptr = new char[sIPAddrInfoArray[currentIndex].fIPAddrStr.Len + 2];
        289         ::strcpy(sIPAddrInfoArray[currentIndex].fIPAddrStr.Ptr, theAddrStr);
        290
        291
        292         struct hostent* theDNSName = NULL;
        293         if (lookupDNSName) //convert this addr to a dns name, and store it
        294         {   theDNSName = ::gethostbyaddr((char *)&theAddr->sin_addr, sizeof(theAddr->sin_addr), AF_INET);
        295         }
        296
        297         if (theDNSName != NULL)
        298         {
        299             sIPAddrInfoArray[currentIndex].fDNSNameStr.Len = ::strlen(theDNSName->h_name);
        300             sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr = new char[sIPAddrInfoArray[currentIndex].fDNSNameStr.Len         + 2];
        301             ::strcpy(sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr, theDNSName->h_name);
        302         }
        303         else
        304         {
        305             //if we failed to look up the DNS name, just store the IP addr as a string
        306             sIPAddrInfoArray[currentIndex].fDNSNameStr.Len = sIPAddrInfoArray[currentIndex].fIPAddrStr.Len;
        307             sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr = new char[sIPAddrInfoArray[currentIndex].fDNSNameStr.Len         + 2];
        308             ::strcpy(sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr, sIPAddrInfoArray[currentIndex].fIPAddrStr.Ptr);
        309         }
        310         //move onto the next array index
        311         currentIndex++;
        312
        313     }
        314 #ifdef __Win32__
        315     ::closesocket(tempSocket);
        316 #elif defined(USE_SIOCGIFNUM)
        317     delete[] ifc.ifc_buf;
        318     ::close(tempSocket);
        319 #else
        320 #error
        321 #endif
        322
        323 #else // !__Win32__
        324
        325     //Most of this code is similar to the SIOCGIFCONF code presented in Stevens,
        326     //Unix Network Programming, section 16.6
        327
        328     //Use the SIOCGIFCONF ioctl call to iterate through the network interfaces
        329     static const UInt32 kMaxAddrBufferSize = 2048;
        330
        331     struct ifconf ifc;
        332     ::memset(&ifc,0,sizeof(ifc));
        333     struct ifreq* ifr;
        334     char buffer[kMaxAddrBufferSize];
        335
        336     int tempSocket = ::socket(AF_INET, SOCK_DGRAM, 0);
        337     if (tempSocket == -1)
        338         return;
        339
        340     ifc.ifc_len = kMaxAddrBufferSize;
        341     ifc.ifc_buf = buffer;
        342
        343 #if __linux__ || __linuxppc__ || __solaris__ || __MacOSX__ || __sgi__ || __osf__
        344     int err = ::ioctl(tempSocket, SIOCGIFCONF, (char*)&ifc);
        345 #elif __FreeBSD__
        346     int err = ::ioctl(tempSocket, OSIOCGIFCONF, (char*)&ifc);
        347 #else
        348     #error
        349 #endif
        350     if (err == -1)
        351         return;
        352
        353 #if __FreeBSD__
        354     int netdev1, netdev2;
        355     struct ifreq *netdevifr;
        356     netdevifr = ifc.ifc_req;
        357     netdev1 = ifc.ifc_len / sizeof(struct ifreq);
        358     for (netdev2=netdev1-1; netdev2>=0; netdev2--)
        359         {
        360         if (ioctl(tempSocket, SIOCGIFADDR, &netdevifr[netdev2]) != 0)
        361             continue;
        362         }
        363 #endif
        364
        365     ::close(tempSocket);
        366     tempSocket = -1;
        367
        368     //walk through the list of IP addrs twice. Once to find out how many,
        369     //the second time to actually grab their information
        370     char* ifReqIter = NULL;
        371     sNumIPAddrs = 0;
        372
        373     for (ifReqIter = buffer; ifReqIter < (buffer + ifc.ifc_len);)
        374     {
        375         ifr = (struct ifreq*)ifReqIter;
        376         if (!SocketUtils::IncrementIfReqIter(&ifReqIter, ifr))
        377             return;
        378
        379         // Some platforms have lo as the first interface, so we have code to
        380         // work around this problem below
        381         //if (::strncmp(ifr->ifr_name, "lo", 2) == 0)
        382         //  Assert(sNumIPAddrs > 0); // If the loopback interface is interface 0, we've got problems
        383
        384         //Only count interfaces in the AF_INET family.
        385         if (ifr->ifr_addr.sa_family == AF_INET)
        386             sNumIPAddrs++;
        387     }
        388
        389 #ifdef TRUCLUSTER
        390
        391     int clusterAliases = 0;
        392
        393     if (clu_is_member())
        394     {
        395         /* loading the vector table */
        396       if (clua_getaliasaddress_vector == NULL)
        397       {
        398         clucall_stat    clustat;
        399         struct sockaddr_in  sin;
        400
        401         clustat = clucall_load("libclua.so", clua_vectors);
        402         int context = 0;
        403         clua_status_t      addr_err;
        404
        405         if (clua_getaliasaddress_vector != NULL)
        406           while ( (addr_err = clua_getaliasaddress
        407               ((struct sockaddr*)&sin, &context)) == CLUA_SUCCESS )
        408           {
        409         sNumIPAddrs++;
        410         clusterAliases++;
        411           }
        412       }
        413
        414     }
        415
        416 #endif // TRUCLUSTER
        417
        418     //allocate the IPAddrInfo array. Unfortunately we can't allocate this
        419     //array the proper way due to a GCC bug
        420     UInt8* addrInfoMem = new UInt8[sizeof(IPAddrInfo) * sNumIPAddrs];
        421     ::memset(addrInfoMem, 0, sizeof(IPAddrInfo) * sNumIPAddrs);
        422     sIPAddrInfoArray = (IPAddrInfo*)addrInfoMem;
        423
        424     //Now extract all the necessary information about each interface
        425     //and put it into the array
        426     UInt32 currentIndex = 0;
        427
        428 #ifdef TRUCLUSTER
        429         // Do these cluster aliases first so they'll be first in the list
        430         if (clusterAliases > 0)
        431         {
        432                 int context = 0;
        433                 struct sockaddr_in sin;
        434                 clua_status_t      addr_err;
        435
        436                 while ( (addr_err = clua_getaliasaddress ((struct sockaddr*)&sin, &context)) == CLUA_SUCCESS )
        437                 {
        438                         char* theAddrStr = ::inet_ntoa(sin.sin_addr);
        439
        440                         //store the IP addr
        441                         sIPAddrInfoArray[currentIndex].fIPAddr = ntohl(sin.sin_addr.s_addr);
        442
        443                         //store the IP addr as a string
        444                         sIPAddrInfoArray[currentIndex].fIPAddrStr.Len = ::strlen(theAddrStr);
        445                         sIPAddrInfoArray[currentIndex].fIPAddrStr.Ptr = new char[sIPAddrInfoArray[currentIndex].fIPAd        drStr.Len + 2];
        446                         ::strcpy(sIPAddrInfoArray[currentIndex].fIPAddrStr.Ptr, theAddrStr);
        447
        448                         //convert this addr to a dns name, and store it
        449                         struct hostent* theDNSName = ::gethostbyaddr((char *)&sin.sin_addr,
        450                                                                                         sizeof(sin.sin_addr), AF_INET        );
        451                         if (theDNSName != NULL)
        452                         {
        453                                 sIPAddrInfoArray[currentIndex].fDNSNameStr.Len = ::strlen(theDNSName->h_name);
        454                                 sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr = new char[sIPAddrInfoArray[currentInd        ex].fDNSNameStr.Len + 2];
        455                                 ::strcpy(sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr, theDNSName->h_name);
        456                         }
        457                         else
        458                         {
        459                                 //if we failed to look up the DNS name, just store the IP addr as a string
        460                                 sIPAddrInfoArray[currentIndex].fDNSNameStr.Len = sIPAddrInfoArray[currentIndex].fIPAd        drStr.Len;
        461                                 sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr = new char[sIPAddrInfoArray[currentInd        ex].fDNSNameStr.Len + 2];
        462                                 ::strcpy(sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr, sIPAddrInfoArray[currentInde        x].fIPAddrStr.Ptr);
        463                         }
        464
        465                         currentIndex++;
        466                 }
        467         }
        468 #endif // TRUCLUSTER
        469
        470     for (ifReqIter = buffer; ifReqIter < (buffer + ifc.ifc_len);)
        471     {
        472         ifr = (struct ifreq*)ifReqIter;
        473         if (!SocketUtils::IncrementIfReqIter(&ifReqIter, ifr))
        474         {
        475             Assert(0);//we should have already detected this error
        476             return;
        477         }
        478
        479         //Only count interfaces in the AF_INET family
        480         if (ifr->ifr_addr.sa_family == AF_INET)
        481         {
        483             char* theAddrStr = ::inet_ntoa(addrPtr->sin_addr);
        484
        485             //store the IP addr
        486             sIPAddrInfoArray[currentIndex].fIPAddr = ntohl(addrPtr->sin_addr.s_addr);
        487
        488             //store the IP addr as a string
        489             sIPAddrInfoArray[currentIndex].fIPAddrStr.Len = ::strlen(theAddrStr);
        490             sIPAddrInfoArray[currentIndex].fIPAddrStr.Ptr = new char[sIPAddrInfoArray[currentIndex].fIPAddrStr.Len +         2];
        491             ::strcpy(sIPAddrInfoArray[currentIndex].fIPAddrStr.Ptr, theAddrStr);
        492
        493             struct hostent* theDNSName = NULL;
        494             if (lookupDNSName) //convert this addr to a dns name, and store it
        495             {   theDNSName = ::gethostbyaddr((char *)&addrPtr->sin_addr, sizeof(addrPtr->sin_addr), AF_INET);
        496             }
        497
        498             if (theDNSName != NULL)
        499             {
        500                 sIPAddrInfoArray[currentIndex].fDNSNameStr.Len = ::strlen(theDNSName->h_name);
        501                 sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr = new char[sIPAddrInfoArray[currentIndex].fDNSNameStr.        Len + 2];
        502                 ::strcpy(sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr, theDNSName->h_name);
        503             }
        504             else
        505             {
        506                 //if we failed to look up the DNS name, just store the IP addr as a string
        507                 sIPAddrInfoArray[currentIndex].fDNSNameStr.Len = sIPAddrInfoArray[currentIndex].fIPAddrStr.Len;
        508                 sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr = new char[sIPAddrInfoArray[currentIndex].fDNSNameStr.        Len + 2];
        509                 ::strcpy(sIPAddrInfoArray[currentIndex].fDNSNameStr.Ptr, sIPAddrInfoArray[currentIndex].fIPAddrStr.Pt        r);
        510             }
        511
        512             //move onto the next array index
        513             currentIndex++;
        514         }
        515     }
        516
        517     Assert(currentIndex == sNumIPAddrs);
        518 #endif
        519
        520     //
        521     // If LocalHost is the first element in the array, switch it to be the second.
        522     // The first element is supposed to be the "default" interface on the machine,
        523     // which should really always be en0.
        524     if ((sNumIPAddrs > 1) && (::strcmp(sIPAddrInfoArray[0].fIPAddrStr.Ptr, "127.0.0.1") == 0))
        525     {
        526         UInt32 tempIP = sIPAddrInfoArray[1].fIPAddr;
        527         sIPAddrInfoArray[1].fIPAddr = sIPAddrInfoArray[0].fIPAddr;
        528         sIPAddrInfoArray[0].fIPAddr = tempIP;
        529         StrPtrLen tempIPStr(sIPAddrInfoArray[1].fIPAddrStr);
        530         sIPAddrInfoArray[1].fIPAddrStr = sIPAddrInfoArray[0].fIPAddrStr;
        531         sIPAddrInfoArray[0].fIPAddrStr = tempIPStr;
        532         StrPtrLen tempDNSStr(sIPAddrInfoArray[1].fDNSNameStr);
        533         sIPAddrInfoArray[1].fDNSNameStr = sIPAddrInfoArray[0].fDNSNameStr;
        534         sIPAddrInfoArray[0].fDNSNameStr = tempDNSStr;
        535     }
        536 }
        537 #endif  //__FreeBSD__
        538
        539
        540
        541 #ifndef __Win32__
        542 Bool16 SocketUtils::IncrementIfReqIter(char** inIfReqIter, ifreq* ifr)
        543 {
        544     //returns true if successful, false otherwise
        545
        546 #if __MacOSX__
        547     *inIfReqIter += sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len;
        548
        549     //if the length of the addr is 0, use the family to determine
        550     //what the addr size is
        551     if (ifr->ifr_addr.sa_len == 0)
        552 #else
        553     *inIfReqIter += sizeof(ifr->ifr_name) + 0;
        554 #endif
        555     {
        556         switch (ifr->ifr_addr.sa_family)
        557         {
        558             case AF_INET:
        559                 *inIfReqIter += sizeof(struct sockaddr_in);
        560                 break;
        561             default:
        562                 *inIfReqIter += sizeof(struct sockaddr);
        563 //              Assert(0);
        564 //              sNumIPAddrs = 0;
        565 //              return false;
        566         }
        567     }
        568     return true;
        569 }
        570 #endif
        571
        572 Bool16 SocketUtils::IsMulticastIPAddr(UInt32 inAddress)
        573 {
        574     return ((inAddress>>8) & 0x00f00000) == 0x00e00000; //  multicast addresses == "class D" == 0xExxxxxxx == 1,1,1,0        ,<28 bits>
        575 }
        576
        577 Bool16 SocketUtils::IsLocalIPAddr(UInt32 inAddress)
        578 {
        579     for (UInt32 x = 0; x < sNumIPAddrs; x++)
        580         if (sIPAddrInfoArray[x].fIPAddr == inAddress)
        581             return true;
        582     return false;
        583 }
        584
        585 void SocketUtils::ConvertAddrToString(const struct in_addr& theAddr, StrPtrLen* ioStr)
        586 {
        587     //re-entrant version of code below
        588     //inet_ntop(AF_INET, &theAddr, ioStr->Ptr, ioStr->Len);
        589     //ioStr->Len = ::strlen(ioStr->Ptr);
        590
        591     sMutex.Lock();
        592     char* addr = inet_ntoa(theAddr);
        593     strcpy(ioStr->Ptr, addr);
        594     ioStr->Len = ::strlen(ioStr->Ptr);
        595     sMutex.Unlock();
        596 }
        597
        598 UInt32 SocketUtils::ConvertStringToAddr(const char* inAddrStr)
        599 {
        600     return ntohl(::inet_addr(inAddrStr));
        601 }
        602
    How do I declare a variable of the right type, then do a memcpy() in this case?
    Last edited by biggyK; 05-29-2006 at 03:23 AM.

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    First you find the right forum. C++ code does not belong on the C forum.


    Quzah.
    Hope is the first step on the road to disappointment.

  11. #11
    Registered User
    Join Date
    May 2006
    Posts
    19

    quzah


    DSS is a mix of C/C++ code, so originally I've posted this question to C and C++ forums alltogether, but Salem told to not create double posts.

    People started to help me here and my question is a continuation of their suggestions.

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    First thing would be for you to annotate the listing with the line numbers which are causing you problems.

    Yeah, moved back to the C++ forum.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    May 2006
    Posts
    19
    Hello Salem ,

    I've annotated the listing with the line numbers (see above).

    Below I'll paste the SocketUtils.h in case you need reference to this file also:

    Code:
         26     File:       SocketUtils.h
         27
         28     Contains:   Some static routines for dealing with networking
         29
         30
         31 */
         32
         33 #ifndef __SOCKETUTILS_H__
         34 #define __SOCKETUTILS_H__
         35
         36 #ifndef __Win32__
         37 #include <sys/socket.h>
         38 #include <netinet/in.h>
         39 #include <net/if.h>
         40 #endif
         41
         42 #include "ev.h"
         43
         44 #include "OSHeaders.h"
         45 #include "MyAssert.h"
         46 #include "StrPtrLen.h"
         47 #include "OSMutex.h"
         48
         49 #ifdef __solaris__
         50     #ifndef INADDR_NONE
         51         #define INADDR_NONE     0xffffffff      /* -1 return from inet_addr */
         52     #endif
         53 #endif
         54
         55 class SocketUtils
         56 {
         57     public:
         58
         59         // Call initialize before using any socket functions.
         60         // (pass true for lookupDNSName if you want the hostname
         61         // looked up via DNS during initialization -- %%sfu)
         62         static void Initialize(Bool16 lookupDNSName = true);
         63
         64         //static utility routines
         65         static Bool16   IsMulticastIPAddr(UInt32 inAddress);
         66         static Bool16   IsLocalIPAddr(UInt32 inAddress);
         67
         68         //This function converts an integer IP address to a dotted-decimal string.
         69         //This function is NOT THREAD SAFE!!!
         70         static void ConvertAddrToString(const struct in_addr& theAddr, StrPtrLen* outAddr);
         71
         72         // This function converts a dotted-decimal string IP address to a UInt32
         73         static UInt32 ConvertStringToAddr(const char* inAddr);
         74
         75         //You can get at all the IP addrs and DNS names on this machine this way
         76         static UInt32       GetNumIPAddrs() { return sNumIPAddrs; }
         77         static inline UInt32        GetIPAddr(UInt32 inAddrIndex);
         78         static inline StrPtrLen*    GetIPAddrStr(UInt32 inAddrIndex);
         79         static inline StrPtrLen*    GetDNSNameStr(UInt32 inDNSIndex);
         80
         81     private:
         82
         83         //Utility function used by Initialize
         84 #ifndef __Win32__
         85         static Bool16 IncrementIfReqIter(char** inIfReqIter, ifreq* ifr);
         86 #endif
         87         //For storing relevent information about each IP interface
         88         struct IPAddrInfo
         89         {
         90             UInt32      fIPAddr;
         91             StrPtrLen   fIPAddrStr;
         92             StrPtrLen   fDNSNameStr;
         93         };
         94
         95         static IPAddrInfo*              sIPAddrInfoArray;
         96         static UInt32                   sNumIPAddrs;
         97         static OSMutex                  sMutex;
         98 };
         99
        100 inline UInt32   SocketUtils::GetIPAddr(UInt32 inAddrIndex)
        101 {
        102     Assert(sIPAddrInfoArray != NULL);
        103     Assert(inAddrIndex < sNumIPAddrs);
        104     return sIPAddrInfoArray[inAddrIndex].fIPAddr;
        105 }
        106
        107 inline StrPtrLen*   SocketUtils::GetIPAddrStr(UInt32 inAddrIndex)
        108 {
        109     Assert(sIPAddrInfoArray != NULL);
        110     Assert(inAddrIndex < sNumIPAddrs);
        111     return &sIPAddrInfoArray[inAddrIndex].fIPAddrStr;
        112 }
        113
        114 inline StrPtrLen*   SocketUtils::GetDNSNameStr(UInt32 inDNSIndex)
        115 {
        116     Assert(sIPAddrInfoArray != NULL);
        117     Assert(inDNSIndex < sNumIPAddrs);
        118     return &sIPAddrInfoArray[inDNSIndex].fDNSNameStr;
        119 }
        120
        121 #endif // __SOCKETUTILS_H__
        122

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > SocketUtils.cpp:375: warning: cast from `char*' to `ifreq*' increases required alignment of target type
    > 375 ifr = (struct ifreq*)ifReqIter;
    Would become
    Code:
    struct ifreq temp;
    memcpy( &temp, ifReqIter, sizeof temp );
    ifr = &temp;
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    Registered User
    Join Date
    May 2006
    Posts
    19
    Thanks man,

    Could you please give me an example here also for:

    Code:
    SocketUtils.cpp:422: warning: cast from `UInt8*' to `SocketUtils::IPAddrInfo*' increases required alignment of target type
    
    SocketUtils.cpp:482: warning: cast from `sockaddr*' to `sockaddr_in*' increases required alignment of target type

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 10-27-2006, 01:21 PM
  2. DxEngine source code
    By Sang-drax in forum Game Programming
    Replies: 5
    Last Post: 06-26-2003, 05:50 PM
  3. Lines from Unix's source code have been copied into the heart of Linux????
    By zahid in forum A Brief History of Cprogramming.com
    Replies: 13
    Last Post: 05-19-2003, 03:50 PM
  4. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM
  5. C source code for int25 or code help
    By Unregistered in forum C Programming
    Replies: 0
    Last Post: 09-26-2001, 02:04 AM