g++ -D_GLIBCXX_DEBUG #impractical

After I build my program with this flag, i get random run-time crashes due to “invalid pointer at free()” whenever i use a stringstream.

I think the stringstream binary was pre-compiled without this compiler flag

Advertisements

gdb stop@simple assignments #compiler optimize

Toggle between -O2 and -O0, which is the default non-optimized compilation.

In my definition, A “simple assignment” is one without using functions. It can get value from another variable or a literal. Simple assignments are optimized away under -O2, so gdb cannot stop on these lines. This applies to break point or step-through.

In particular, if you breakpoint on a simple assignment then “info breakpoint” will show a growing hit count on this breakpoint, but under -O2 gdb would never stop there. -O0 works as expected.

As another illustration, if an if-block contains nothing but simple assignment, then gdb has nowhere to stop inside it and will only stop after the if-block. You won’t know whether you entered it. -O0 works as expected.

ODR@functions(+classes)

OneDefinitionRule is more strict on global variables (which have static duration). You can’t have 2 global variables sharing the same name. Devil is in the details:

As explained in various posts, you declare the same global variable in a header file that’s included in various compilation units, but you allocate storage in exactly one compilation unit. Under a temporary suspension of disbelief, let’s say there are 2 allocated storage for the same global var, how would you update this variable?

With free function f1(), ODR is more relaxed. http://www.drdobbs.com/cpp/blundering-into-the-one-definition-rule/240166489 explains the Lessor ODR vs Greater ODR. Lessor ODR is simpler and more familiar, forbidding multiple (same or different) definitions of func1() within one compilation unit.

My focus today is the Greater ODR therein. Obeying Lessor ODR, the same function are often included via a header file and compiled into multiple binary files. Linker actually sees multiple (hopefully identical) physical copies of func1(). Two copies of this function are usually identical definitions. If they actually have different definitions, compiler/linker can’t easily notice and are not required to verify, so no build error (!) but you could hit strange run time errors.

Java linker is simpler and never cause any problem so I never look into it.

c++non-void function without a return value!

Strictly, undefined behavior not a compiler error. https://stackoverflow.com/questions/9936011/if-a-function-returns-no-value-with-a-valid-return-type-is-it-okay-to-for-the explains the rationale.

However, in practice,

  • For an int function the compiler could return any int value.
  • For functions returning type AA, I don’t know what is returned. Could it be a default-constructed instance of AA?
    • My specific case — I modified a well-behaving function to introduce an exception. I then added a catch-all block without a return value. Actually worked fine. So some instance of AA is actually returned!

 

linker dislikes(non-generic)function definition in shared header

I used to feel header files are optional so we can make do without them if they get in our ways. This post shows they aren’t optional in any non-trivial c++ project. There is often only one (or few) correct way to structure the header vs implementation files. You can’t make do without them.

Suppose MyHeader.h is included in 2 cpp files and they are linked to create an executable.

A class definition is permitted in MyHeader.h:

class Test89{
void test123(){}
};

However, if the test123() is a free function, then linker will fail with “multiple definition” of this function when linking the two object files.

http://stackoverflow.com/questions/29526585/why-defining-classes-in-header-f iles-works-but-not-functions explains the rules

* repeated definition of function (in a shared header) must be inlined * repeated class definition (in a shared header) is permitted for a valid reason (sizing…). Since programmers could not only declare but define a member function in such a class, in a header, the compiler silently treats such member functions as inline

delete base class ptr,with non-virtual dtor #base dtor runs!

This correct code produces ” ~B ~A” i.e. reverse construction sequence. But what if “virtual” removed?

I said it’s undefined behavior, but what if we know it does do something?

I correctly predicted “~A”, tested in minGw.

class A{
public: virtual ~A(){ cout<<" ~ A"<<endl; }
};
class B: public A{
public: ~B(){ cout<<" ~ B "; }
};
int main(){
A * p = new B;
delete p;
cin.get();
}

typedef – non-optional in this case

Someone asked me to write a utility function to print any STL container, in my own loop. I suggested we follow the STL convention to use iterator inputs. Echoed on http://stackoverflow.com/questions/4657767/how-to-templatize-a-function-on-an-stl-container-that-has-an-iterator. However, what if we pass the container itself as input (assuming it’s a standard-conforming container)?

template
void dump(const CT& cont) {
    typedef typename CT::const_iterator iterator; //no choice
    iterator i;
    //won’t compile — CT::const_iterator i;
    for(i = cont.begin();   i!= cont.end();   ++i){
        cout<<*i <<" "<<endl;
    }
}

This works but the typedef isn’t sugar-coating. Without it you get

dependent-name ` M::const_iterator’ is parsed as a non-type, but instantiation yields a type

Very loosely, CT::const_iterator i suggests to the compiler to create a concrete type for i but CT::const_iterator is not a generic type, not “concretized” [1]. Solution — The typedef dresses up this “generic type” as if it’s an end-user type, usable in a variable declaration

[1] remember the Barcap FMD eval objects?

3 implicit conversions by c++ compiler – const

# a literal “any string” is treated as char const *. If you must assign such a literal string to a ptr-to-char variable, you must cast away the constness (Macquaries)

# If you have a const method in a non-const class instance, and if inside that method you access some instance fields, those fields are implicitly converted to const variables. See P215 [[eff STL]]

# as stated in other posts (like http://bigblog.tanbin.com/2012/02/c-const-methods-mean-this-is-bitwise.html), in a const method, “this” is converted to a ptr-to-const.

# http://bigblog.tanbin.com/2012/04/non-primitive-field-in-const-method.html