public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
From: Eljay Love-Jensen <eljay@adobe.com>
To: Philip <snzzbk@gmail.com>, GCC-help <gcc-help@gcc.gnu.org>
Subject: Re: reinterpret_casting a non-POD
Date: Sun, 17 Aug 2008 04:08:00 -0000	[thread overview]
Message-ID: <C4CC329F.7DE9%eljay@adobe.com> (raw)
In-Reply-To: <25c035550808160442n695bb421m79e58ede2d203e0@mail.gmail.com>

Hi Philip,

I think the risks are...

*** Pointer aliasing may cause you problems.

*** Intra-structure padding may cause you problems.

*** Alignment requirements that are not fulfilled by your "acquire memory"
may cause you problems.

*** Even if it works on your machine, the non-portable code may cause you
problems if you ever port it, including upgrading compilers from the same
vendor on the same platform.

*** If the class is a general purpose SDK class, I'd strongly consider *not*
making the member functions inline, rather move their implementation out
into the Point.cpp file.  (If your downstream users are a captive audience,
such as you are making an SDK for your own team, or making an SDK which is
only used intra-company, then the issue is much less important.)  Plus, for
a general purpose SDK, I would implement the synthetic routines that the
compiler will generate for you, such as destructor, copy constructor, and
assignment operator, yada yada.  (I'd even go as far as consider the "next
step" and change Point to an interface-only class with virtual functions and
a static factory function, with the implementation class not exposed in the
SDK API.)

#define SOAPBOX

I'd fix those problems by trying to encapsulate the behavior you are trying
to do into the Point class itself.

I don't know what your preferred paradigm for getters/setters naming
convention, so I used the Objective-C / Cocoa -ish one.

I also added the Print/Scan and Write/Read pairs.  And the I/O streaming <<
and >> operator glue.

---------------------------------------- Point.h
// Probably not the best way to get a float NaN.
float const FloatNaN = 0.0f / 0.0f;

class Point
{
  float m[3];
public:
  Point() { m[0] = m[1] = m[2] = FloatNaN; }
  Point(float x, float y, float z) { m[0] = x; m[1] = y; m[2] = z; }
  float* AsFloatArray3() { return m; } // Exposes implementation.
  float X() const { return m[0]; }
  float Y() const { return m[1]; }
  float Z() const { return m[2]; }
  void SetX(float x) { m[0] = x; }
  void SetY(float y) { m[1] = y; }
  void SetZ(float z) { m[2] = z; }
  void Print(std::ostream&) const; // Human readable printer.
  void Scan(std::istream&); // Round-trip scan-from-print.
  void Write(std::ostream&) const; // Binary writer.
  void Read(std::istream&); // Binary reader.
};

inline
std::ostream& operator << (std::ostream& output, Point const& point)
{
  point.Print(output);
  return output;
}

inline
std::istream& operator >> (std::istream& input, Point& point)
{
  point.Scan(input);
  return input;
}
----------------------------------------

Here are some principles:

Put the code in your class, so that for the USERS of your class, it's easy
to use like butter.  Even if that means your class's implementation is ugly
in spots, it is better for the ugliness to be encapsulated in the class
rather than distributed amongst the users.  That's the primary target
audience of your class's API.

The primary target audience of your class's code is the poor maintenance
programmer (could be your future self a few years down the road) who has to
figure out your class, enhance your class, or debug it.  Make your class as
programmer friendly as possible.  Lots of useful comments.  Nice, consistent
formatting.  Don't make statements unnecessarily convoluted.  Trust the
compiler's optimizer.  The only time you should employ "befuddling code" is
if profiling indicates that -- for performance reasons -- the code needs to
have loops manually unrolled or some other heinous obfuscation techniques.
Make sure those manual machinations are well documented, and maybe keep the
"slow" routine around for sanity checking and self-testing.  [The above
Point class is *NOT* a showcase example of programmer friendly formatting.
But it's a pretty simple example, where making it "programmer friendly"
would make it look bloated with unnecessary busy-comments.  Good for
increasing kLOC, if you are paid by the kLOC.]

#undef SOAPBOX

HTH,
--Eljay

      reply	other threads:[~2008-08-16 12:31 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-16 12:31 Philip
2008-08-17  4:08 ` Eljay Love-Jensen [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=C4CC329F.7DE9%eljay@adobe.com \
    --to=eljay@adobe.com \
    --cc=gcc-help@gcc.gnu.org \
    --cc=snzzbk@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).