Debugging some code with Visual Studio and I was surprised to find that the values of the property of an object looked great before the call into a method and then were corrupted as soon as I entered the method:
The call comes from here. The debugger reports that thingA.property = 0.14
method1()
{
Thing thingA;
object.method2(thingA)
}
and goes into here and the debugger reports thingMine.property = 4.0E-315#DEN
method2(Thing thingMine)
{
....
}
When I change scope back up to method1 the property looks fine and scoping back down to method2 the property takes on a wildly different value.
What can cause the value to change? Back in the old days with C, I can mangle memory by fooling around with pointers. However, there's nothing fancy about this code. There are no (explicit) pointers. The compiler is happy with the cast / class of all the objects. There is no fancy inheritance or overloading.
To add more detail, Thing is not simply a class with properties and methods. Its properties are objects, but still not very fancy:
class Thing {
public:
AnotherThing thingInsideAThing;
...
}
It is the property of AnotherThing that is getting mangled.
My understand of pass-by-value is based upon my ancient schooling in C. I thought calling a method would push an explicit copy of thingA onto the stack. Does it push a bad address for thingA.object onto the stack? I thought pass-by-value was always the safest way to forward information into a method.
Where do I begin to understand the underlying problem?
I believe the answer is found in the way that Visual Studio displays values for objects that are
pass by value
pass by constant reference
The code below assigns the proper value to a. However, for my object, the debugger reports #DEN when I ask it to display thing.x.
method(Thing thing)
{
double a = thing.x;
}
However, when I write:
method(const Thing& thing)
{
double a = thing.x;
}
the debugger reports the expected value for thing.x.
I recognize that there is a difference between pass by value and pass by constant reference. However, in my case I don't think that there is a practical difference.
Related
this is a VERY simplified version of the question to make it obvious what i am asking. I cannot seem to find it on Stack Overflow but i am probably searching using the wrong words!
Here is a Template Class with the obvious parts removed.
template <class T, bool clip = true>
class BOUNDED_VAL {
public:
BOUNDED_VAL(T initialMin, T intialMax) :locked(false) {
assert_or_throw(intialMax >= initialMin, HD_ERR_MINMAX_REVERSED);
min = initialMin;
max = intialMax;
value = initialMin;
};etc.
// assert_or_throw is a typedef which asserts during debug builds to prevent programmer mistakes (especially my own) or throws a rich catachable runtime error for user input just in case something gets around user input limit checking during release builds (A hard wall). Belt and braces approach...
Now i know i can set this up as an initialised private class member variable like so:
private:
BOUNDED_VAL<int> testBoundInt = BOUNDED_VAL<int>(0, 10);
BUT
Does this create a new BOUNDED_VAL and then copy it over the member variable (or compiler smooshes this away during optimisation)?
Is there a more succinct way of doing it which i am just not finding? I know the following do not work but for example:
private:
BOUNDED_VAL<int> testBoundInt(0,10);
or
private:
BOUNDED_VAL<int>(0,10) testBoundInt;
I am self taught in C++ so it might be an obvious question...but you never know...
Many Thanks
I know the following do not work but for example:
private:
BOUNDED_VAL<int> testBoundInt(0,10);
But this will work, provided your compiler was written in the last decade:
BOUNDED_VAL<int> testBoundInt{0,10};
It looks like you might be using an outdated textbook to learn C++ that does not cover uniform initialization syntax from the current version of C++. You are strongly encouraged to get updated learning material.
Does this [copy initialization] create a new BOUNDED_VAL and then copy it over the member variable (or compiler smooshes this away during optimisation)?
This actually depends on the C++ version your compiler supports, and is configured to use. Depending on several factors it gets "smooshed" away, or we take a scenic trip to the countryside, where an object gets constructed, then a second object gets copy-constructed, and the first object deleted.
But this is now a secondary topic, since uniform initialization syntax solves the original problem.
I'm still relatively new to Objective C and easily confused by the various types. I am using code from the SquareCam sample project, incorporated into a larger project. It works fine, but now I want to save the videoDataOutputQueue, which is of type dispatch_queue_t so that I can use it elsewhere in the project. It has to pass through some C++ code before finally ending up back in Objective C code. Therefore I am trying to add it to a structure that I already have, as a void * (void *videoDataOutputQueue;)
However, I have not found the right way to assign it without getting a EXC_BAD_ACCESS runtime error. Since dispatch_queue_t is a C++ object, can't I just use it's address?
declared in the interface for squarecamviewcontroller:
#interface SquareCamViewController : UIViewController <UIGestureRecognizerDelegate, AVCaptureVideoDataOutputSampleBufferDelegate,UIActionSheetDelegate>
{
AVCaptureVideoPreviewLayer *previewLayer;
AVCaptureVideoDataOutput *dataOutput;
AVCaptureVideoDataOutput *videoDataOutput;
dispatch_queue_t videoDataOutputQueue;
<other stuff>
}
later in the code:
- (void)setupAVCapture
{
<other stuff from the sample code>
MYSTRUCT myStruct = (MYSTRUCT)struct; // make a pointer to the structure
myStruct->videoDataOutputQueue = (void *)videoDataOutputQueue; <<<- bad access here at runtime
<other stuff>
}
Clearly this is not the right way and I don't understand what I am doing. I have some hints from other posts but I'm missing something.
Thanks,
Ken
You have made your question unnecessarily difficult to understand because the "code" you've presented has syntax errors. It's clearly not your real code, so we can't guess what's really supposed to be happening. For example, you use the struct reserved keyword as though it were a value.
Given where you say the bad access occurs, this has nothing to do with the dispatch queue. It looks like your myStruct variable is supposed to be a pointer to a structure of some kind but is just a garbage pointer. So, the attempt to assign a value to one of its fields ends up writing to an invalid memory address. It doesn't really matter what the nature of the field is.
The problem is apparently exactly in the code you omitted as "<other stuff from the sample code>". So, you need to show that. Indeed, you need to show your real code.
Beyond that, dispatch_queue_t is a C type. It's not specific to Objective-C. Therefore, you can use it across all C-based languages. There's no need to use a void*.
A dispatch queue, like all dispatch objects, is reference counted. If you're keeping a long-term reference to it, you need to make sure it stays alive. So, you need to retain it with dispatch_retain(). Likewise, you need to release it when you're done with it using dispatch_release(). (Don't forget to release the old value when you replace a reference you're keeping with another.)
To the folks marking this as duplicate: it is not; the other question addresses enums which are compile-time constants. This is not a constant integral expression thus the solution would be very different. Please see my code below more carefully before suggesting this has already been answered in another question, as it has not in any way. I am checking the value of a member variable on an object, information created at runtime, and I'm curious what I can do with that in this context.
I'm at a point where I need to use something to make the compiler fail if the user of my API does something she should not.
I don't know if that's possible, it is? The options I mention above are primarily run-time, right?
For example, suppose you have a function:
void doSomethingIncredible(AwesomeClass amazingObject)
{
//perform life-changing work here except:
if (amazingObject.isntAmazing) //a bool property of object
//uh oh, life sucks, I refuse to compile this
Now calling this function will change how you live your life in all respects, except for occasions in which amazingObject has a particular property switched on, for example, in which case, I want the compiler to not even allow this to pass, i.e. cannot run the program.
Somewhere in the body of the function is a c++ mechanism that forces compiling to fail, which alerts the user that you cannot use this function for such an inferior un-amazing object.
Is this possible?
To clarify, this is something I want to do a compile time based the contents of a variable, as shown in my example above. The suggestion to use static_assert does not apply here.
You can either static_assert() a condition at compile time (C++11)
static_assert(false, "Hey user! You suck!");
or use
#if (some_erroneous_condition_to_be_avoided)
#error "Hey user! You suck!"
#endif
if you have a GNU-compatible compiler (g++, clang++, etc.)
The only way I can see to get it compile time checked is to subclass AwesomeClass and restrict the new class' creation to only be able to create objects where amazingObject.isntAmazing is never true. Then change the signature to;
void doSomethingIncredible(AwesomeAndAmazingClass amazingObject)
That will prevent the call to the method for objects that are simply awesome but not amazing.
As a maybe more illustrative example (not compiled, so consider pseudo code);
class Thing {
protected:
Color _color;
Shape _shape;
public:
Thing(Color color, Shape shape) {
_color=color; _shape=shape;
}
}
class GreenThing : Thing {
public:
GreenThing(Shape shape) : Thing(Color.Green, shape) {}
}
void doSomethingIncredible(GreenThing specialThing)
{
// specialThing here is still a Thing, but also compile time
// checked to also always be a GreenThing
}
It is impossible. The value of the variable is decided at runtime, but you want to throw a compile-time error depending on the runtime value.
One problem I am struggling with while writing a C++ extension for Ruby is to make it really safe even if the user does silly things. He should get exceptions then, but never a SegFault. A concrete problem is the following: My C++ class has a non-trivial constructor. Then I use the Rice API to wrap my C++ class. If the user redefines initialize() in his Ruby code, then the initialize() function created by Rice is overwritten and the object is neither allocated nor initialized. One toy example could be the following:
class Person {
public:
Person(const string& name): m_name (name) {}
const string& name() const { return m_name; }
private:
string m_name;
}
Then I create the Ruby class like this:
define_class<Person>("Person")
.define_constructor(Constructor<Person, const string&>(), Arg("name"))
.define_method("name", &Person::name);
Then the following Ruby Code causes a Segfault
require 'MyExtension'
class Person
def initialize
end
end
p = Person.new
puts p.name
There would be two possibilities I would be happy about: Forbid overwriting the initialize function in Ruby somehow or check in C++, if the Object has been allocated correctly and if not, throw an exception.
I once used the Ruby C API directly and then it was easy. I just allocated a dummy object consisting of a Null Pointer and a flag that is set to false in the allocate() function and in the initialize method, I allocated the real object and set the flag to true. In every method, I checked for that flag and raised an exception, if it was false. However, I wrote a lot of stupid repetitive code with the Ruby C API, I first had to wrap my C++ classes such that they were accessible from C and then wrap and unwrap Ruby types etc, additionally I had to check for this stupid flag in every single method, so I migrated to Rice, which is really nice and I am very glad about that.
In Rice, however, the programmer can only provide a constructor which is called in the initialize() function created by rice and the allocate() function is predefined and does nothing. I don't think there is an easy way to change this or provide an own allocate function in an "official" way. Of course, I could still use the C API to define the allocate function, so I tried to mix the C API and Rice somehow, but then I got really nasty, I got strange SegFaults and it was really ugly, so I abandoned that idea.
Does anyone here have experiences with Rice or does anyone know how to make this safe?
How about this
class Person
def initialize
puts "old"
end
alias_method :original_initialize, :initialize
def self.method_added(n)
if n == :initialize && !#adding_initialize_method
method_name = "new_initialize_#{Time.now.to_i}"
alias_method method_name, :initialize
begin
#adding_initialize_method = true
define_method :initialize do |*args|
original_initialize(*args)
send method_name, *args
end
ensure
#adding_initialize_method = false
end
end
end
end
class Person
def initialize
puts "new"
end
end
Then calling Person.new outputs
old
new
i.e. our old initialize method is still getting called
This uses the method_added hook which is called whenever a method is added (or redefined) at this point the new method already exists so it's too late to stop them from doing it. Instead we alias the freshly defined initialize method (you might want to work a little harder to ensure the method name is unique) and define another initialize that calls the old initialize method first and then the new one.
If the person is sensible and calls super from their initialize then this would result in your original initialize method being called twice - you might need to guard against this
You could just throw an exception from method_added to warn the user that they are doing a bad thing, but this doesn't stop the method from being added: the class is now in an unstable state. You could of course realias your original initialize method on top of their one.
In your comment you say that in the c++ code, this is a null pointer. If it is possible to call a c++ class that way from ruby, I'm afraid there is no real solution. C++ is not designed to be fool-proof. Basically this happens in c++;
Person * p = 0;
p->name();
A good c++ compiler will stop you from doing this, but you can always rewrite it in a way the compiler cannot detect what is happening. This results in undefined behaviour, the program can do anything, including crash.
Of course you can check for this in every non-static function;
const string& Person::name() const
{
if (!this) throw "object not allocated";
return m_name;
}
To make it easier and avoid double code, create a #define;
#define CHECK if (!this) { throw "object not allocated"; }
const string& name() const { CHECK; return m_name; }
int age() const { CHECK; return m_age; }
However it would have been better to avoid in ruby that the user can redefine initialize.
This is an interesting problem, not endemic to Rice, but to any extension which separates allocation and initialization into separate methods. I do not see an obvious solution.
In Ruby 1.6 days, we did not have allocate/initialize; we had new/initialize. There may still be code left over in Rice which defines MyClass.new instead of MyClass.allocate and MyClass#initialize. Ruby 1.8 separated allocation and initialization into separate methods (http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/23358) and Rice uses the new "allocation framework". But it has the problem you pointed out.
The allocate method cannot construct the object, because it does not have the parameters to pass to the constructor.
Rice could define .new instead (as was done on 1.6), but this doesn't work with #dup and Marshal.load. However, this is probably the safer (and right) solution.
I now think that this is a problem of the Rice library. If you use Rice in the way it is documented, you get these problems and there is no obvious way to solve it and all workarounds have drawbacks and are terrible. So I guess the solution is to fork Rice and fix this since they seem to ignore bug reports.
I am calling a function in a API that returns a Answer object. Under some conditions, the API will return EMPTY_answer, which is defined as such:
#define EMPTY_answer ((Answer)0)
of course, attempting to access a Answer variable or function from an EMPTY_answer object crashes the application.
Trying to test for it using if(lAnswer == EMPTY_answer) also crashes the application. Is there any way to detect if the API is returning EMPTY_answer?
Edit:
I didn't code the api and I can't modify it in any way, I'm just digging through .h files trying to figure this out. And yes, I am aware that casting 0 to a class is a bit too creative to put it mildly. I just noticed that the == operator is overridden
(...)
class ExportedByJS0CORBA Answer
{
(...)
int __stdcall operator==(Answer *ipt) const;
}
the function being called is
static SubClassOfAction Query();
I'm simplifying names and quite a few layers of inheritance
To be more precise, it crashes with a Segmentation Fault.
Instead of doing a very ugly cast which is almost guaranteed to trigger undefined behavior, just make a static global variable which is used as the "empty" answer. You don't need to use this object in any way, just make it exist so it can be used as a sentinel.
In Answer.h:
extern const Answer EMPTY_answer;
In Answer.cpp:
const Answer EMPTY_answer; // use any constructor parameters that will be appropriate
If Answer is a class type, as the text of your questions suggest, then (Answer) 0 will construct a temporary Answer object using the constructor that accepts 0 as an argument (apparently such constructor exists). In this case attempting to access the members of that object will not crash anything, unless Answer class is specifically implemented to crash in this case (intentionally or unintentionally). So your "Of course..." claim makes no sense whatsoever. There's no immediate reason for such code to crash.
If you observe crashed in someAnswer == EMPTY_answer comparison, that would either mean that the implementation of == operator is buggy, or that either the LHS or the RHS are not valid objects. For example, it might turn out that it is illegal (by design) to construct an Answer object by conversion from 0. If so, then you should simply stop using (Answer) 0 in your code and find another, correctly supported object value to indicate an empty answer.
your original method of just checking for EMPTY_answer is the right way to solve this. Your real problem is why that crashes. What type is lAnswer? Or Answer for that matter... you can't cast 0 to a class like that.