title: Is there an orthodox way to avoid compiler warning C4309 - "truncation of constant value" with binary file output?
body: <p>My program does the common task of writing binary data to a file, conforming to a certain non-text file format. Since the data I'm writing is not already in existing chunks but instead is put together byte by byte at runtime, I use <code>std::ostream::put()</code> instead of <code>write()</code>. I assume this is normal procedure.</p>
  
  <p>The program works just fine. It uses both <code>std::stringstream::put()</code> and <code>std::ofstream::put()</code> with two-digit hex integers as the arguments. But I get compiler warning C4309: "truncation of constant value" (in VC++ 2010) whenever the argument to <code>put()</code> is greater than 0x7f. Obviously the compiler is expecting a <code>signed char</code>, and the constant is out of range. But I don't think any truncation is actually happening; the byte gets written just like it's supposed to.</p>
  
  <p>Compiler warnings make me think I'm not doing things in the normal, accepted way. The situation I described has to be a common one. <em>Is there are common way to avoid such a compiler warning</em>? Or is this an example of a pointless compiler warning that should just be ignored?</p>
  
  <p>I thought of two inelegant ways to avoid it. I could use syntax like <code>mystream.put( char(0xa4) )</code> on every call. Or instead of using <code>std::stringstream</code> I could use <code>std::basic_stringstream&lt; unsigned char &gt;</code>, but I don't think that trick would work with <code>std::ofstream</code>, which is not a templated type. I feel like there should be a better solution here, especially since <code>ofstream</code> is meant for writing binary files.</p>
  
  <p>Your thoughts?</p>
  
  <p><strong>--EDIT--</strong></p>
  
  <p>Ah, I was mistaken about <code>std::ofstream</code> not being a templated type. It is actually <code>std::basic_ofstream&lt;char&gt;</code>, but I tried that method that and realized it won't work anyway for lack of defined methods and polymorphic incompatibility with <code>std::ostream</code>.</p>
  
  <p>Here's a code sample:</p>
  
  <pre><code>stringstream ss;
  int a, b;
  /* Do stuff */
  ss.put( 0 );
  ss.put( 0x90 | a ); // oddly, no warning here...
  ss.put( b );        // ...or here
  ss.put( 0xa4 );     // C4309
  </code></pre>