vijayan121 1,152 Posting Virtuoso
ifstream file("a:\\crypnums.txt");
vector<int> numbers ; 
int i ;
while( file >> i ) numbers.push_back(i) ;
assert( file.eof() ) ;

or

ifstream file("a:\\crypnums.txt");
vector<int> numbers ; 
istream_iterator<int> begin(file), end ;
copy( begin, end, back_inserter(numbers) ) ;
assert( file.eof() ) ;

both assume that the integers are seperated by one or more whitespaces.

vijayan121 1,152 Posting Virtuoso

I kind of figured what it does, but I haven't used enum yet, and I don't understand how numeric_limits works.

an unnamed enum as in enum { char_bits = numeric_limits<unsigned char>::digits }; in normal code is equivalent to const int char_bits = numeric_limits<unsigned char>::digits ; inside the body of a class, it is an just an easy way to define a constant (the value of which is known at compile time).
for numeric limits, see: http://www.dinkumware.com/manuals/?manual=compleat&page=limits2.html
ie: "http://www.dinkumware.com/manuals/?manual=compleat&page=limits2.html"

Endianness? What's that

see: http://en.wikipedia.org/wiki/Endianness

But it doesn't let me use _sep to divide the bytes. It just prints a long string of 1's and 0's.

we can do that quite easily. this is one way:

template <typename T>  class binary
  {
    public:
      explicit binary( const T value, const char *sep = " " )
         : _value( value ), _sep( sep ) {}

      friend ostream& operator<<( ostream& os, const binary& b )
      {
        bitset< sizeof(T)*char_bits > bs( b._value ) ;
        const string& str = bs.to_string() ;
        for( size_t i=0 ; i<sizeof(T) ; ++i )
           os << str.substr( i*char_bits, char_bits ) << b._sep ;
        return os ;
      }
    private:
      T  _value;
      string _sep;
  };

I don't understand what the example is doing. Why is that different from what I have?

in the above example, writing friend ostream& operator<<( ostream& os, [B]const[/B] binary& b ) implies that as far as this function is concerned, b can not be modified; neither b._value or b._sep. …

vijayan121 1,152 Posting Virtuoso

> it is probably wiser not to hold the seperator string (_sep) as a pointer; this might get us into trouble if a temporary was passed as the second constructor arg
>> But I thought because it's const that can't ever happen.

binary<int> to_binary( int n )
{
  char does_not_exist_once_fn_returns[] = "\n" ;
  binary<int> ret( n, sep ) ;
  return ret ;
}

when the function returns, lifetime of does_not_exist_once_fn_returns is over, but the returned object will hold the pointer. also, as in this example a non-const can be converted implicitly to a const.

> the hard coded assumption that CHAR_BITS==8 should be done away with
>> Isn't a byte always 8 bits? And a nybble is 4 bits?
in common usage, yes. but not as per the C standard. to quote it:
byte: The unit of storage in the execution environment large enough to hold any member of the basic character set of the execution environment. ... A byte is composed of a contiguous sequence of bits, the number of which is implementation-defined.
-- ISO/IEC 9899:1990(E) right on page 2
and the C++ standard is compatible with the C standard for the memory model of POD types.

>> you lost me with the enum and digits thing
C and cplusplus provide library headers (<limits.h> in C, <limits> in C++) which allow us to write correct code inspite of implementation differences. for a numeric type T, std::numeric_limits<T>::radix gives the radix and …

vijayan121 1,152 Posting Virtuoso

...I have 100 commands and whenever the commands are pressed the corresponding function + arguements...

it is much more flexible to represent functions as objects . this would allow free functions, function objects and member functions to be treated polymorphically. also, since these are objects, they can support operations (eg.bind). in the following example, boost.function and boost.bind are used (from the boost libraries); however, both function and bind would be part of c++0x (they are in tr1).

#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <map>
using namespace std ;
using namespace boost ;

struct function_one // function object
{
  void operator() ( const string& arg ) const 
  { cout << "function_one( " << arg << " )\n" ; }
};

void function_two( const string& arg ) // free function
{ cout << "function_two( " << arg << " )\n" ; }

struct object
{
  explicit object( int ii = 0 ) : i(0) {}
  int i ;
  void function_three( const string& arg ) // member function
  { cout << "object::function_three( " << arg << " )\n" ; ++i ; }
};

int main()
{
  typedef function< void ( const string& ) > function_t ;
  typedef pair< function_t, string > fn_with_arg_t ;
  map< string, fn_with_arg_t > function_map ;
  function_map[ "function object" ] = fn_with_arg_t( function_one(), "one" );
  function_map[ "free function" ] = fn_with_arg_t( function_two, "two" ) ;
  object obj ;
  function_map[ "member function" ] = 
     fn_with_arg_t( bind( &object::function_three, ref(obj), _1 ), "three" );
  string key ;
  while( getline( cin, key …
vijayan121 1,152 Posting Virtuoso

a. it is probably wiser not to hold the seperator string (_sep) as a pointer; this might get us into trouble if a temporary was passed as the second constructor arg
b. the hard coded assumption that CHAR_BITS==8 should be done away with
c. we could reuse the functionality available in std::bitset<>
d. and we can enable assignment by making the member variables non-const

#include <iostream> // for C++ I/O
#include <string>   // for C++ strings
#include <bitset>
#include <limits>
using namespace std;

namespace hamrick 
{
  enum { char_bits = numeric_limits<unsigned char>::digits };
  template <typename T>  class binary
  {
    public:
      explicit binary( const T value, const char *sep = " " )
         : _value( value ), _sep( sep ) {}

      friend ostream& operator<<( ostream& os, const binary& b )
      {
        typedef bitset< sizeof(T)*char_bits > bs ;
        return os << bs( b._value ) << b._sep ;
      }
    private:
      T  _value;
      string _sep;
  };

  template <>  class binary<string> 
  {
    public:
      explicit binary( const string& value, const char *sep = " " )
        : _value( value ), _sep( sep ) {}

    friend ostream& operator<<( ostream& os, const binary& b )
    {
      for( size_t i=0 ; i < b._value.size() ; ++i )
        os << bitset< char_bits >( b._value[i] ) << b._sep ;
      return os ;
    }
    private:
      string _value;
      string _sep;
  };
}

int main()
{
  cout<< hamrick::binary<int>( 1234 ) <<endl;
  cout<< hamrick::binary<string>( "ABCD" ) <<endl;

  for ( int a = 0; a < 256; a++ )
    cout<< hamrick::binary<char>( a …
vijayan121 1,152 Posting Virtuoso

That makes sense. But even when I disable intrinsics, the result is the same. Is Visual C++ really using a different function than the one in the CRT source folder?

it appears so - the disassembly code i posted is with intrinsics disabled. perhaps there are different versions of sources for the debug version of the library and the release version. i do not have the CRT source for visual studio with me (i tested it on vc++ express); you could look into the CRT source tree for a directory containing assembly code.

vijayan121 1,152 Posting Virtuoso

without intrinsics, the code generated for hamrick::strlen is:

;    COMDAT ?strlen@hamrick@@YAIPBD@Z
_TEXT    SEGMENT
_str$ = 8                        ; size = 4
?strlen@hamrick@@YAIPBD@Z PROC                ; hamrick::strlen, COMDAT

; 49   :     // treat a null pointer as an empty string
; 50   :     size_t len = 0;
; 51   : 
; 52   :     if ( str != 0 ) {

    mov    ecx, DWORD PTR _str$[esp-4]
    xor    eax, eax
    test    ecx, ecx
    je    SHORT $LN1@strlen

; 53   :       // find the end and count each character
; 54   :       while ( *str != '\0' ) {

    cmp    BYTE PTR [ecx], al
    je    SHORT $LN1@strlen
    npad    2
$LL2@strlen:

; 55   :         ++len;
; 56   :         ++str;

    add    ecx, 1
    add    eax, 1
    cmp    BYTE PTR [ecx], 0
    jne    SHORT $LL2@strlen
$LN1@strlen:

; 57   :       }
; 58   :     }
; 59   : 
; 60   :     return len;
; 61   :   }

    ret    0
?strlen@hamrick@@YAIPBD@Z ENDP                ; hamrick::strlen
_TEXT    ENDS

for hamrick::xstrlen, it is

PUBLIC    ?xstrlen@hamrick@@YAIPBD@Z            ; hamrick::xstrlen
; Function compile flags: /Ogtpy
;    COMDAT ?xstrlen@hamrick@@YAIPBD@Z
_TEXT    SEGMENT
_str$ = 8                        ; size = 4
?xstrlen@hamrick@@YAIPBD@Z PROC                ; hamrick::xstrlen, COMDAT

; 65   :     const char *eos = str;

    mov    ecx, DWORD PTR _str$[esp-4]
    mov    eax, ecx
$LL2@xstrlen:

; 66   :     while( *eos++ ) ;

    mov    dl, BYTE PTR [eax]
    add    eax, 1
    test    dl, dl
    jne    SHORT $LL2@xstrlen

; 67   :     return( eos - str - 1 );

    sub    eax, ecx
    sub    eax, 1

; 68   :   }

    ret    0
?xstrlen@hamrick@@YAIPBD@Z ENDP                ; hamrick::xstrlen …
vijayan121 1,152 Posting Virtuoso

> the assembly output doesn't show me the code generated for C++'s strlen(), just my strlen() and xstrlen().

the microsoft C++ compiler recognizes and directly inserts optimized inline code for several functions (including strlen). functions like strlen in the Standard C library are available in both intrinsic and non-intrinsic forms. we can control the use of intrinsics by inserting #pragma intrinsic statements into the source code or using the -Oi compiler switch.

vijayan121 1,152 Posting Virtuoso

if the enums have consecutive integral values (as in this case), we can increment by adding one to the value.

#include <iostream>
int main()
{
  enum level { FRESHMAN=0, SOPHMORE=1, JUNIOR=2, SENIOR=3 } ;
  const char* const literal_level[] = 
                            { "FRESHMAN", "SOPHMORE", "JUNIOR", "SENIOR" } ;
  for( level lev = FRESHMAN ; lev <= SENIOR ; lev = level(lev+1) )
      std::cout << literal_level[ lev ] << '\n' ;
}
vijayan121 1,152 Posting Virtuoso

the server will bind to an address and start listening on it. the client socket is usually dynamically bound and tries to connect to the socket at the address the server has bound. so the port the client tries to connect to should be the same as the one the server used in the call to bind.
1234 is not an ideal choice for the port though. see http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers

will this connection be established? can't say. the port may already be in use (for 1234, this is likely in windows), the connection may be blocked/dropped by a firewall etc.

vijayan121 1,152 Posting Virtuoso

C++ annotations (groningen) is one of the books you could check out. available online at
http://www.icce.rug.nl/documents/cplusplus/

vijayan121 1,152 Posting Virtuoso

for mciSendString, link to winmm.lib

vijayan121 1,152 Posting Virtuoso

include winsock2.h
link to ws2_32.lib
needs ws2_32.dll

vijayan121 1,152 Posting Virtuoso
const char* const months = "*ABCDEFGHIJKL" ;

inline char month_to_code( int m ) 
{ 
  assert( m>0 && m<13 ) ;
  return months[ m ] ; 
}

inline int code_to_month( char c ) 
{ 
  const char* p = strchr( months, toupper(c) ) ; 
  assert( p!=0 && p!=months ) ; 
  return p - months ; 
}

// etc

after sorting out issues that Ancient Dragon pointed out

vijayan121 1,152 Posting Virtuoso

btw, I've already seen this: http://code.google.com/p/google-sparsehash/
was wondering if there is more like this ? any other containers' implementation.. ?

documentation for dense/sparse hash/map/table is available at
http://google-sparsehash.googlecode.com/svn/trunk/doc/index.html
dense_hash/map trades memory for performance, sparse versions are very memory efficient, but slow. the performance is good, but the difference between O(N logN) and O(N) [ log N ] should be about 20 to 21 times for our data set. the gcc implementation is really a first beta; i think the focus was on getting out a working version, not performance.

you may also find this link interesting
http://code.google.com/p/google-perftools/wiki/GooglePerformanceTools
TCMalloc is really fast.

both are truly free (under the nonviral BSD license); you could use it in anyway you want without restrictions.

more code is available at http://code.google.com/
i've not tried any of the others.

~s.o.s~ commented: Nice +22
vijayan121 1,152 Posting Virtuoso

since we are printing only the duplicates, the time taken to print them out will depend on the number of duplicate values. any way, here are the results for the earlier code.
note: i have replaced gcc <random> with boost<random.hpp>; gcc 4.30 stage 1 snapshot's implementation of uniform_int<> distribution seems to be buggy; these results would be more accurate.

#include <iostream>
#include <iterator>
#include <vector>
#include <unordered_set>
#include <set>
#include <google/dense_hash_set>
#include <boost/random.hpp>
#include <boost/timer.hpp>
#include <algorithm>
#include <fstream>
using namespace std;

//note: requires gcc 4.3; compile with -std=c++0x

void get_dup_set( const vector<int>& in, vector<int>& dups )
{
  dups.clear() ;
  set<int> set ; 
  for( size_t i=0 ; i<in.size() ; ++i )
    if( !set.insert( in[i] ).second ) dups.push_back( in[i] ) ;
}

void get_dup_hash( const vector<int>& in, vector<int>& dups )
{
  dups.clear() ;
  unordered_set<int> set ; // hash impl. with buckets (tr1)
  for( size_t i=0 ; i<in.size() ; ++i )
    if( set.find( in[i] ) == set.end() ) set.insert( in[i] ) ;
    else dups.push_back( in[i] ) ; 
}

void get_dup_google( const vector<int>& in, vector<int>& dups )
{
  dups.clear() ;
  google::dense_hash_set< int, hash<int> > set ; 
  set.set_empty_key(-1) ;
  for( size_t i=0 ; i<in.size() ; ++i )
    if( !set.insert( in[i] ).second ) dups.push_back( in[i] ) ;
}

int main()
{
  const int N = { 1024*1024*4 };
  vector<int> in(N), dups ;
  dups.reserve(N) ;
  boost::mt19937 twister ;
  boost::uniform_int<> distribution(1,N/2) ;
  boost::variate_generator< boost::mt19937, boost::uniform_int<> > 
                                   generator(twister,distribution) ;
  for( size_t i=0 ; i<in.size() ; ++i ) in[i] = generator() ;
  boost::timer timer ;
  get_dup_set(in,dups) ; …
vijayan121 1,152 Posting Virtuoso

here is a performance measure

#include <iostream>
#include <iterator>
#include <vector>
#include <unordered_set>
#include <set>
#include <google/dense_hash_set>
#include <random>
#include <boost/timer.hpp>
using namespace std;

//note: requires gcc 4.3; compile with -std=c++0x

void get_dup_set( const vector<int>& in, vector<int>& dups )
{
  dups.clear() ;
  set<int> set ; 
  for( size_t i=0 ; i<in.size() ; ++i )
    if( !set.insert( in[i] ).second ) dups.push_back( in[i] ) ;
}

void get_dup_hash( const vector<int>& in, vector<int>& dups )
{
  dups.clear() ;
  unordered_set<int> set ; // hash impl. with buckets (tr1)
  for( size_t i=0 ; i<in.size() ; ++i )
    if( set.find( in[i] ) == set.end() ) set.insert( in[i] ) ;
    else dups.push_back( in[i] ) ; 
}

void get_dup_google( const vector<int>& in, vector<int>& dups )
{
  dups.clear() ;
  google::dense_hash_set< int, hash<int> > set ; 
  set.set_empty_key(-1) ;
  for( size_t i=0 ; i<in.size() ; ++i )
    if( !set.insert( in[i] ).second ) dups.push_back( in[i] ) ;
}

int main()
{
  const int N = { 1024*1024*4 };
  vector<int> in(N), dups ;
  dups.reserve(N) ;
  mt19937 twister ;
  uniform_int<> distribution(1,N/2) ;
  variate_generator< mt19937, uniform_int<> > generator(twister,distribution) ;
  for( size_t i=0 ; i<in.size() ; ++i ) in[i] = generator() ;
  boost::timer timer ;
  get_dup_set(in,dups) ;
  cout << "using std::set: " << timer.elapsed() << " seconds\n" ;
  dups.reserve(N) ;
  timer.restart() ;
  get_dup_hash(in,dups) ;
  cout << "using tr1 hash: " << timer.elapsed() << " seconds\n" ;
  dups.reserve(N) ;
  timer.restart() ;
  get_dup_google(in,dups) ;
  cout << "using google hash: " << timer.elapsed() << " seconds\n" ;
}

g++43 -std=c++0x -O3 -I/usr/local duplicates.cpp ; ./a.out
using std::set: 37.8828 …

vijayan121 1,152 Posting Virtuoso

>I honestly don't think the difference ... will be noticeable to the user in an I/O bound program.

true; it may not even be measurable. i/o will dominate everything else.
note: the current version of boost has an implementation of tr1 (in std::tr1) that would work with most compilers.

vijayan121 1,152 Posting Virtuoso

using a hash technique would be faster; linear time

#include <iostream>
#include <iterator>
#include <vector>
#include <unordered_set>
using namespace std;

//note: requires gcc 4.3; compile with -std=c++0x

int main()
{
  int a[] = { 1, 2, 3, 4, 5, 3, 6, 7, 5, 8, 9, 3, 5, 2, 8 };
  unordered_set<int> set ; // hash impl. with buckets (tr1)
  cout << "duplicates\n-------------\n" ;
  for( size_t i=0 ; i<sizeof(a)/sizeof(a[0]) ; ++i )
    if( set.find( a[i] ) == set.end() ) set.insert( a[i] ) ;
    else cout << a[i] << '\n' ; 
}
vijayan121 1,152 Posting Virtuoso

after exiting from main, the following actions are performed:
a. call destructors of objects with static storage
b. call atexit functions
c. deinit the C runtime library
during this, it was detected that some dynamically allocated memory block is invalid. this can occur due to a variety of reasons; but the fragment pHead->nBlockUse usually indicates that you are trying to free memory that has already benn freed. (it is also possible that a block header was corrupted by writing beyond the bounds of allocated memory in an adjecent block). if there is no instance of any such error in your own code, it would have been caused by something incorrect in a library that you are using.

vijayan121 1,152 Posting Virtuoso

My question still stands. A set reorders the sequence just as much as a map. The order preserving behavior you get (assuming that's what you're talking about with the python example) isn't in your choice of a set, but the order in which you process the items from your vector.

true. the set is used only to check if the element is a duplicate (and is discarded on return from the function). the sequence is processed in the original order. it just finds (and in this example prints out) the duplicate values; it does not modify the original sequence at all (it is a const).

vijayan121 1,152 Posting Virtuoso

> why didn't you go with a map instead
because i was working under the premise:
if you are not alowed to reorder the original sequence, but are allowed to use auxiliary storage

> ...it also marks each of the duplicates for later use. That's a great deal
> more flexible than what you have ...
true.

here is an extract from the python cookbook (this is to remove, not just identify duplicates) [Raymond Hettinger, 2002]

def uniq(alist)    # Fastest order preserving
  set = {}
  return [set.setdefault(e,e) for e in alist if e not in set]

def uniq(alist)    # Fastest without order preserving
  set = {}
  map(set.__setitem__, alist, [])
  return set.keys()
vijayan121 1,152 Posting Virtuoso

if you are not alowed to reorder the original sequence, but are allowed to use auxiliary storage

#include <vector>
#include <set>
#include <iostream>
#include <string>
using namespace std;

template< typename CNTR >
void print_duplicates( const CNTR& cntr )
{
  set< typename CNTR::value_type > unique ;
  for( size_t i=0 ; i<cntr.size() ; ++i )
    if( !unique.insert( cntr[i] ).second )
      cout << "duplicate " << cntr[i] << '\n' ;
}

int main()
{
  string str ; cin >> str ;
  vector<int> v( str.begin(), str.end() ) ;
  print_duplicates(v) ;
}

this would take O( N log N ). instead of a set, if you use a hashtable with a good hash function, you could do this in linear time.

vijayan121 1,152 Posting Virtuoso

a constructor which a. can be called with one arg b. is not marked explicit is also an implicit conversion operator.

struct A{}; struct C {};
struct B 
{ 
   B(const A&) {} 
   explicit B(const C& ) {}
};
A a ; C c ;
B b = a ; // ok, equiv to B b( B(a) ) ;
// B b2 = c ; // error, no implicit conversion from C to B
B b3 = B(c) ; // ok, conversion is explicit
vijayan121 1,152 Posting Virtuoso

... i.e it implicitly functions as a constant pointer to another variable, ...

except at point of initialization, it is like a constant pointer to another variable that is implicitly dereferenced.

int i = 57 ;
int& r = i ;
int* const p = &i ;
r == *p == i ;
&r == &(*p) == &i ;
sizeof(r) == sizeof(*p) == sizeof(i) == sizeof(int) ;
typeid(r) == typeid(*p) == typeid(int) ;
vijayan121 1,152 Posting Virtuoso
#include <vector>
#include <algorithm>
using namespace std ;
int main()
{
  vector<int> cntr( 20U, 7 ) ;
  int* array = new int [ cntr.size() ] ;
  typedef vector<int>::iterator iterator ;
  int x = 0 ;
  for( iterator it = cntr.begin() ; it != cntr.end() ; ++it, ++x )
  {
   array[x] = *it ; // ok
   // array[it] = *it ; // error, it is not an integral value
  }
  
  // the easy way
  copy( cntr.begin(), cntr.end(), array ) ;
  delete[] array ;
}
vijayan121 1,152 Posting Virtuoso
#include <vector>
#include <boost/tokenizer.hpp>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
using namespace boost;

int main()
{
  string str = "The boost tokenizer library provides a flexible "
                       "and easy to use way to break of a string or other "
                       "character sequence into a series of tokens.\n"
                       "Here is a simple example that will break up a "
                       "paragraph into words.\n";
  tokenizer<> toker( str );
  vector<string> words( toker.begin(), toker.end() ) ;
  cout << "there are " << words.size() << " words\n" ;
  cout << "words[6]: " << words[6] << '\n' ;
}
vijayan121 1,152 Posting Virtuoso

except in a trivial situation, where the compiler can optimize away the storage, a reference is stored in memory as an address. so for, struct A { double& ref ; A(double&d) : ref(d) {} }; sizeof(A) == sizeof(double*)
when a reference is passed to a function, what is passed is the address. it is easy enough to check this out

cfile.c
------------

#include <stdio.h>

void c_function( double* const pointer )
{
  printf( "c_function:: pointer: %p\t*pointer: %f\n", pointer, *pointer ) ;
  *pointer += 333.444 ; 
  printf( "c_function:: pointer: %p\t*pointer: %f\n", pointer, *pointer ) ;
}

references.cpp
------------------------------

#include <iostream>

// cheat on the type; exploit type unsafe linkage of C
// extern "C" => linkage is "C", type system is still C++
extern "C" void c_function( double& dbl ) ;

int main()
{
  double value = 1.234 ;
  std::cout << "main:: &value: " << &value << "\tvalue: " << value << '\n' ;
  c_function(value) ;
  std::cout << "main:: &value: " << &value << "\tvalue: " << value << '\n' ;
}

> gcc -Wall -std=c89 -c cfile.c
> g++ -Wall -std=c++98 references.cpp cfile.o
> ./a.out
main:: &value: 0xbfbfe950 value: 1.234
c_function:: pointer: 0xbfbfe950 *pointer: 1.234000
c_function:: pointer: 0xbfbfe950 *pointer: 334.678000
main:: &value: 0xbfbfe950 value: 334.678

this would be the case with all C++ compilers

vijayan121 1,152 Posting Virtuoso

you must be using a microsoft compiler (or a compiler with abi compatibility with the microsoft compiler). if the destructor is virtual, an entry needs to be made for the destructor in the vtbl of the class. for delete ptr_abc , two things need to happen.
a. the correct destructor must be called polymorphically
b. the appropriate operator delete must also be called polymorphically.
the microsoft technique is to synthesize a thunk (called the scalar deleting destructor) which does step a. followed by step b. and place the entry in the vtbl. so, you get a linker error (undefined external operator delete).
if the destructor is not virtual, no such thunk is required and therefore you do not get an error. (you will get the error only if you call delete).

in other compilers, the techniques used are different (and not as efficient). so, for instance in g++, you would not get a linker error unless you explicitly call delete somewhere.

for more information, see Stan Lippman's Inside the C++ Object Model (Addison-Wesley Professional, 1996)

vijayan121 1,152 Posting Virtuoso

members or base class sub-objects cannot be initialized inside the body of the constructor; they can only be assigned to. initialization is always before the body of the constructor executes. if not initialized expliciltly using colon initialization, the implementation will provide default initialization if available. for any member which does not have default initialization (constants and references are examples of these), an explicit initialization would have to be provided.

struct A
{
  A() 
     // error 1: must_be_initialized must be initialized
  {
    must_be_initialized = 0 ; // error 2: constant can't be assigned to
  }
  const int must_be_initialized ;
};
vijayan121 1,152 Posting Virtuoso

Also bear in mind that some old versions of turbo c++ and nearly all versions of Visual Studio do not adhere to the standard

the c++ front-end from Edison Design Group is the only implementation to support the complete C++ standard ISO/IEC 14882:2003. see: http://www.edg.com/index.php?location=c_lang
a good test for compiler conformance is to look at the implementation of the Dinkumware C++ library
(a completely conforming implementation of the standard C++ library ISO/IEC 14882:1998, as corrected through 2003.). as per dinkumware,
"As a general rule, you can expect reasonably complete library functionality when using Microsoft Visual C++ compilers from V7.1 onward, GCC compilers from V3.0 onward, and all compilers using the EDG front end. Only EDG compilers offer complete Standard C and C++ conformance (when used with Dinkumware libraries), and only EDG V3.5 and later supports fixed-point arithmetic (TR18037)."
http://www.dinkumware.com/manuals/
current versions of the microsoft c++ compiler use libraries from dinkumware; gcc libstdc++ implementations from version 3.4.0 are also fairly conformant. the recently released Turbo C++ 2006 (sep 2006) includes the Dinkumware C++ libraries and my guess is that the conformance would be reasonable.

vijayan121 1,152 Posting Virtuoso

a sequence container can also be initialized with a sequence identified by a pair of iterators.

char cstr[] = "abcdefghijkl" ;
  std::list<int> list2( cstr, cstr+sizeof(cstr) ) ;

in c++0x, the following would be another way:

std::list<int> list5 = { 23, 6, 57, 575, 7575, 75 }; // like aggreagate initializer in C
iamthwee commented: This is c++? -2
vijayan121 1,152 Posting Virtuoso

normally the best online reference is msdn. the ip address control reference is at http://msdn2.microsoft.com/en-us/library/ms671454.aspx
i looked around msdn a bit; but did not see any info on custom colouring this control.
by spying on the ip address control window, it turns out that it has four child windows (each of them an edit control). i suppose that was to be expected. so we could colour the edit controls using the normal WM_CTLCOLOREDIT mechanism. you would need to subclass the ip address control. and in the subclassed window procedure, handle the WM_CTLCOLOREDIT yourself. pass everything else for default handling ( by a return CallWindowProc(....) )
see http://msdn2.microsoft.com/en-us/library/ms633569.aspx#instance_subclassing
on how to subclass a window instance

vijayan121 1,152 Posting Virtuoso

you could write a handler for the EN_UPDATE notification sent by the edit control and force a repaint by InvalidateRect/UpdateWindow.
rich edit controls do not send CTLCOLOR messages; however you can set its background colour by sending it a EM_SETBKGNDCOLOR message.

i've not used WC_IPADDRESS (i've not written any gui code for several years now), but i think it is just an edit control with special formatting/validation. so my guess is that you should be able to treat it like an edit control.

vijayan121 1,152 Posting Virtuoso

...I need the full background of the test control to be black and the text of the edit control to be white, how could I do this?

what are are you returning? you need to return a handle to the brush with which the control background would be painted. eg. for a black background:
return LRESULT( GetStockObject( BLACK_BRUSH ) ) ;

vijayan121 1,152 Posting Virtuoso

Yes but how would one set each of these on one specific control?

for the WM_CTLCLREDIT message,
wparam - handle to the device context for the edit control window (HDC)
lparam - handle to the edit control (HWND)
if you want to make the decision based on the HWND, this is all that is required; if you want to do the same based on control id:

// ...
case WM_CTLCOLOREDIT:
{  
   HDC dc = HDC(wparam) ;
   HWND edit_window = HWND(lparam) ;
   int edit_control_id = GetDlgCtrlID(edit_window) ;     
   switch(edit_control_id)
  {
     // ...
vijayan121 1,152 Posting Virtuoso

BUT the text in the edit control had a different background colour.

The wparam of the message is a handle to the device context; you can use SetTextColor, SetBkMode, SetTextAlign etc. ion it.

vijayan121 1,152 Posting Virtuoso
if( std::find( alist.begin(), alist.end(), x ) != alist.end() )
{ /* do this */ }
vijayan121 1,152 Posting Virtuoso

for controls other than buttons, you could handle the WM_CTLCOLORXXX notification; eg. WM_CTLCOLOREDIT for an edit control.
for buttons, the button needs to be an owner-drawn button; for such a button the system sends the parent window a WM_DRAWITEM message.
see: http://msdn2.microsoft.com/en-us/library/ms673346.aspx

vijayan121 1,152 Posting Virtuoso
struct A
{
   std::string str ;
   explicit A( const char* cstr ) ;
   explicit A( const std::string& s ) ;
};

A::A( const char* cstr ) : str(cstr) {}
A::A( const std::string& s ) { str = s ; }

the constructor using initializer syntax is more efficient; it directly constructs the string from a const char*. the one using assignment first constructs a string using its default constructor and then assigns one string to another.
there would be no difference if the default initialization is trivial (for example an int member); initializer syntax is required if there is no default initialization available(reference or const members, user defined type with no or inaccessible default constructors).

vijayan121 1,152 Posting Virtuoso

...Compiling with the -fpermissive gave me many new errors...

it would not; -fpermissive merely converts some errors into warnings. compile with -fpermissive exactly as you dsescribed in your original post (not with the extern "C" etc.).

vijayan121 1,152 Posting Virtuoso
vijayan121 1,152 Posting Virtuoso

It's just simple maths

void process ( int a, int b ) {
  char var[10];
  process( 0, 0 );
}

You have a char array, so that's 10 bytes.
Two integers - say 4 bytes each (total 8).
Each call has a fixed overhead of several bytes (say saving the return address of the call), another 8.

So that's 26 bytes in this example.
26 * 22460 = 583960...

we need to also take into acount
a. padding that would be added to align data (eg. in the above example, 2 bytes for the char array in a 32 bit architecture).
b. many compilers would also insert canaries on the stack to enable stack smashing protection. microsoft c++ 8, icc 9, gcc on FreeBSD, NetBsd, OpenBSD and SystemX all implement canaries by default. these canaries would be there in every stack frame (see http://en.wikipedia.org/wiki/Stack-smashing_protection#Implementations )

~s.o.s~ commented: nice +20
Rashakil Fol commented: hi +6
vijayan121 1,152 Posting Virtuoso

...modify a const by casting

really you should not.
a constant whose value is known at compile time
a. may (would) be placed into memory with read-only access by the compiler if it has a static storage class.
b. the compiler can (should) treat such a contant as if it is a literal constant. eg.

const size_t N = 78 ;
const_cast<size_t&>(N) = 100 ; // will compile because of the cast
int array[N] ; // will also compile, but the array size is 78, not 100
if( N > 80 ) { /* whatever */ } // dead code!
const int* ptr = &N ;
cout << N << '\t' << *ptr << '\n' ; // N, *ptr have different values

as narue said, that you cannot (should not) modify a const is a good thing.

however, const is handled by the compiler, not the preprocessor; therefore (unlike a #define) it is subject to scoping rules.

const int N = 78 ;
void foo()
{
  cout << N << '\n' ; // 78
  const int N = 100 ;
  cout << N << '\n' ; // 100
  {
     const string N = "N is a string!" ;
     cout << N << '\n' ; // N is a string!
   }
  cout << N << '\n' ; // 100
}
const void* init = cout << N << '\n' ; // 78
vijayan121 1,152 Posting Virtuoso

a. correct your existing code so that it will compile without errors; test it.
b. convert the recursive algorithm to a tail-recursive form.
c. convert the tail-recursive implementation to an iterative one.
for steps b. and c., see:
http://en.wikipedia.org/wiki/Tail_recursion
http://www.nist.gov/dads/HTML/tailrecursn.html

vijayan121 1,152 Posting Virtuoso

Why would you be uncomfortable with the -fpermissive?

because it could pass a serious error as valid code with nasty surprises at runtime. for example,

void foo( const char* cstr )
{
  cstr[0] = 'a' ; // will only give a warning with -fpermissive, 
  // but would cause  disater at runtime
} 

int main()
{
  static const char hello[] = "hello world" ;
  foo( hello  ) ;
  // if function foo is defined in a different translation unit, 
  // the optimizer could eliminate the following as dead code
  // even if foo did work!
  if( hello[0] == 'a' )
  {
    // whatever
  }
}

How do I change the source code to make the const correct?

you need to look at the places where the error was occurring. and make appropriate modifications. eg. if a function wants to modify a string parameter, it should declare it as a char*, not a const char*. and at the place where you are calling the function, you have to ensure that you have a modifiable array of chars.

g++ prior to 3.0 was not a C++ compiler at all (just as turbo C++ is not C++). Non-conforming (incorrect) code that compiled with these versions of g++ would be correctly rejected by later versions. g++ 3.0 was the first version which had a C++ standard library; version 3.4.0 included a complete rewrite of the parser. ISO C++ conformance is pretty good in versions 3.4.0 or above.
the -fpermissive switch was given …

vijayan121 1,152 Posting Virtuoso

Note that the .c and the .cc have classes, so should be C++, right?

right. and audiodiff.cc #includes audiodiff.c
i can't think of solutions other than changing the source (making it const correct) unless you want to use a very old version of g++.

you could also suppress the specific error in your original compile
error: invalid conversion from ‘const char*’ to ‘char*’
(convert it to a mere warning) by using the -fpermissive switch
eg. g++ -fpermissive myfile.cc

the code would then compile in the original form; i would not feel very comfortable about doing this though.

vijayan121 1,152 Posting Virtuoso

the file you are trying to compile it is a C (not C++) file. compile that with gcc, not g++. in your C++ code include the header as follows:

extern "C"
{
  #include "whatever.h"
}
vijayan121 1,152 Posting Virtuoso
vijayan121 1,152 Posting Virtuoso
class D
{
   // ...
   D operator- ( const D& d2 ) const;
   // ...
};
D D::operator- ( const D& d2 ) const
{
  // ...

would also make your code const-correct.