Accessing reference variable from shared_ptr - shared-ptr

I wasn't sure about the title, so apologies in advance if it's not very clear.
The example below illustrates my problem.
When I use new to initialize the shared_ptr from the Member Initialization List then when I assign a value to the &ref_bar everything seems to work fine. However, when I try the same thing with make_shared, which is the preferred way, it doesn't work.
Can you please explain what happens under the hood for this to occur?
Please ignore the "bad" coding in the following example. I've created this to illustrate my problem. I'm interested in what matters the shared_ptr.
#include <iostream>
#include <memory>
class Bar
{
int m_bar;
public:
int &ref_bar;
Bar(int bar_) : m_bar(bar_),ref_bar(m_bar)
{;}
void print()
{
std::cout<< "m_bar = "<<m_bar<<std::endl;
}
};
struct Foo
{
std::shared_ptr<Bar> m_foo;
Foo() : m_foo( std::make_shared<Bar>(Bar(23)) ) // Ex.1
//Foo() : m_foo( new Bar(23) ) // Ex.2
{
m_foo->print();
m_foo->ref_bar = 12;
m_foo->print();
}
};
int main()
{
Foo f;
}
The results are:
Ex.1 >> 23,23 Wrong.
Ex.2 >> 23,12 Ok.
Here's a link to ideone: http://ideone.com/xluYQ9

Fixed when changing the constructor from:
Foo() : m_foo( std::make_shared<Bar>(Bar(23)) ) // Ex.1
to
Foo() : m_foo( std::make_shared<Bar>(23) ) // Ex.1
There's something about calling the constructor inside the make_shared arguments. I still don't know why so if anyone knows more about this please do answer the question in detail.

Related

Coccinelle rule to match foo() call inside an if

So, the problem I stumble upon is that code inside if can be pretty complex, it can be stuff like if (NOT(ret = foo())) and also if (foo() == NULL), and other variations are possible.
To me the obvious answer is the rule line if (...foo()...), but Coccinelle says it fails to parse this.
I tried everything I managed to find or to guess, so far to no avail.
As a demo example, here's a test.c
#include <stddef.h>
#include <stdbool.h>
#define NOT(expr) (!(expr))
void remove_this_call_if_foo_is_called() {}
const char* foo() { return "hello"; }
const char* bar() { return "hello"; }
int main() {
const char* ret;
if (NOT(ret = foo())) {
remove_this_call_if_foo_is_called();
}
if (foo() == NULL) {
remove_this_call_if_foo_is_called();
}
if (foo()) {
remove_this_call_if_foo_is_called();
}
if (bar()) {
// Do not remove if something different from foo() is called.
remove_this_call_if_foo_is_called();
}
}
And I want to remove remove_this_call_if_foo_is_called() calls whenever they're in an if () body and the if condition has foo() call.
A Coccinelle example that unfortunately always removes these lines is:
# rule1 #
##
if (...) {
...
- remove_this_call_if_foo_is_called();
...
}
I was told on IRC, the way to solve it is to surround foo() with <+... and ...+>. So, the working example is:
# rule1 #
##
if (<+...foo()...+>) {
...
- remove_this_call_if_foo_is_called();
...
}
It is unclear though, why this works here, while the <... and ... variations doesn't. As I'm reading the docs any of them should work. This answer is a "community wiki", so feel free to edit it if you know why is that.

Value of multiple struct variables is same unintentionally

I have a code that does OOP like Java.
I have separated the interface and the implementation in separate files names demo.h and demo.c.
demo.h
#ifndef DEMO_H
#define DEMO_H
typedef struct {
/*
This is the variable that will be set by setter method
and its value will be extracted by getter method.
This variable must not be directly accessible by the programmer.
*/
int num;
void (* setNum)(int); // This function will set the value of variable "num".
int (* getNum)(); // This function will return the value of variable "num".
} *Demo; // As objects in java are always called by reference.
Demo newDemo(); // This function will create an instance of class(struct here) Demo and return.
/* This is equivalent to:
Demo obj = new Demo();
int java.
I want my users to create instance of this class(struct here) like this:
Demo obj = newDemo();
here in this code.
*/
#endif
And the implementation:
demo.c
#include <stdlib.h>
#include "demo.h"
Demo demo; /* I have created a global variable so that it is accessible
in setNum and getNum functions. */
void setNum(int num) {
demo->num = num; // This is where the global demo is accessed.
}
int getNum(Demo obj) {
return demo->num; // This is where the global demo is accessed.
}
Demo newDemo() {
Demo obj; // This will be the returned object.
obj = (Demo)malloc(sizeof(*obj)); /* Allocating separate memory to
obj each time this function is called. */
/* Setting the function pointer. */
obj->setNum = setNum;
obj->getNum = getNum;
/* As obj is at different memory location every time this function is called,
I am assigning that new location the the global demo variable. So that each variable
of the Demo class(struct here) must have a different object at different memory
location. */
demo = obj;
return obj; // Finally returning the object.
}
This is how I have implemented the main function:
main.c
#include "demo.h"
#include <stdio.h>
int main() {
void displayData(Demo);
Demo obj1 = newDemo();
Demo obj2 = newDemo();
Demo obj3 = newDemo();
obj1->setNum(5);
obj2->setNum(4);
obj3->setNum(12);
displayData(obj1);
displayData(obj2);
displayData(obj3);
return 0;
}
void displayData(Demo obj) {
int num = obj->getNum();
fprintf(stdout, "%d\n", num);
}
On compilation and execution on my mac book pro:
> gcc -c demo.c
> gcc main.c demo.o -o Demo
> ./Demo
The output is:
12
12
12
But the desired output is:
5
4
12
What am I doing wrong?
Please help.
I don't want my users to pass the struct pointer as an argument as:
Demo obj = newDemo();
obj->setName(obj, "Aditya R.Singh"); /* Creating the program this way was successful as my
header file had the declaration as:
typedef struct demo {
int num;
void (* setNum)(struct demo, int); // This is what I don't desire.
void (* getNum)(struct demo); // This is what I don't desire.
} *Demo;
I want to keep it like the way it is in my current
demo.h*/
/* I don't want to pass obj as an argument. All I want to do this is this way. */
obj->setName("Aditya R.Singh");
Is there any way possible to do this and get the desired output?
Please help, thanks!
I have absolutely no idea of c++, but in your code, I think, demo = obj; is the problem. demo is global, right? It will get overwritten with evety call to newDemo().
Side effect : Memory leak.

Generate two functions with C Preprocessor

I have a project, and a case where I have a few often-changed preprocessor #defines that control how it works--ex:
void myfunction(int num, mystruct* content) {
doSomethingTo(content);
//...
#ifdef FEATURE_X
feature_x(content);
#endif
}
This works fine, although it does have to be recompiled each time, so it's in the "stuff that has to be recompiled each time" file. I would like to push it into a [static] library instead. I'm ok with changing how it's called (already have a function pointer for picking myFunction), so I'd like that to turn into
void myfunction(int num, mystruct* content) {
doSomethingTo(content);
//...
}
void myfunction_featureX(int num, mystruct* content) {
doSomethingTo(content);
//...
feature_x(content);
}
I need to do this in a couple places, so using a separate library (one with and one without -D FEATURE_X) for each isn't an acceptable option. I could do it with copy/paste, but that results in code reuse that carries a risk of fixing a bug in one copy but not the other.
Have the featureX versions of functions call the mainline functions. In your example myfunction_featureX would call myfunction and then do its own thing.
Surely, this is the point at which you change the activation of Feature X from a compile time issue into a run-time issue:
void myfunction(int num, mystruct* content)
{
doSomethingTo(content);
//...
if (FeatureX_Enabled())
feature_x(content);
}
The FeatureX_Enabled() test might be a full function, or it might be simply test an appropriately scoped variable that is defined outside the function — a static variable in the file, or an external variable. This avoids having to futz with the function pointers; it's the same function called as now. Changing a table of function pointers is equivalent to changing a single variable — it involves changing the value of something stored outside the function to change the behaviour of the function.
Would it help if you put myfeature_x in a function table instead?
#include <stdio.h>
#include <string.h>
typedef struct {
int x,y;
} mystruct;
typedef void (*fn_ptr)(mystruct* content);
fn_ptr vtable[10];
#define FEATURE_X_INDEX 0
void feature_x(mystruct *content)
{
printf("y: %d\n", content->y);
}
void myfunction(int num, mystruct* content) {
printf("x: %d\n", content->x);
//...
if (vtable[FEATURE_X_INDEX]) {
vtable[FEATURE_X_INDEX](content);
}
}
int main(void)
{
bzero(vtable, sizeof(vtable));
mystruct s;
s.x = 1;
s.y = 2;
myfunction(0, &s);
if (1) {
//Of course you'd use a more sensible condition.
vtable[FEATURE_X_INDEX] = feature_x;
}
myfunction(0, &s);
return 0;
}
Output:
x: 1
x: 1
y: 2
Then all you need to do is populate the virtual function table with NULLs if that feature is not to be used, and with function pointers if it is to be used. This you can do from wherever you want - your static library for example.. or you can compile feature_x into a dynamic library, load it at runtime and if the loading succeeded populate the function table, and clear the table when the dynamically linked library is unloaded.
I think the only benefit this really gives you over Jonathan Leffler's method is that the code for feature_x doesn't actually need to be linked into the same binary as your other code. If all you need is a runtime switch to turn the feature on or off, a simple if statement should do the trick, as Jonathan Leffler suggested. (Incidentally, there's an if here, too - it checks the function table's content :) )

Unable to pass C struct into function

I'm having trouble passing a struct into a function and I am running into an error:
'PWM_PINS' undeclared (first use in this function)
I am typically able to do this in a C++ compiler without any trouble. I would appreciate some advice as to what I might be doing wrong here.
I have included the relevant parts from the header and c file below.
pwm.h file:
typedef struct PWM_tag{
int PWM_1;
int PWM_2;
int PWM_3;
int PWM_4;
int PWM_5;
int PWM_6;
} PWM;
void PWM_Set( uint32_t channelNum, uint32_t cycle, PWM PWN_PINS );
pwm.c file:
#include "pwm.h"
void PWM_Set( uint32_t ChannelNum, uint32_t cycle, PWM PWN_PINS)
{
if ( ChannelNum == 1 )
{
LPC_PWM1->MR0 = cycle;
LPC_PWM1->MR1 = PWM_PINS.PWM_1;
LPC_PWM1->MR2 = PWM_PINS.PWM_2;
LPC_PWM1->MR3 = PWN_PINS.PWM_3;
LPC_PWM1->MR4 = PWM_PINS.PWM_4;
LPC_PWM1->MR5 = PWM_PINS.PWM_5;
LPC_PWM1->MR6 = PWM_PINS.PWM_6;
}
return;
}
You declared a parameter called PWN_PINS (with an N), but you are referring to PWM_PINS (with an M).
Fixing this typo will address this particular error. There may be more errors, though - it's hard to tell, because the snippet does not show essential parts, such as the declaration of LPC_PWM1 variable.
Is there misspelling in the code?
The function parameter is PWN_PINS.But the code have 5 PWM_PINS, and one PWN_PINS.
I think what you should do is to change all PWN_PINS to PWM_PINS.

C++ Constructor With Parameters Won't Initialize, Errors C2059 and C2228

I'm a C# programmer trying to muddle through C++ to create a Windows Forms Application.
I have a Windows Form that makes use of a user-created class. Basically I'm trying to use a constructor that takes parameters, but my form won't let me initialize the object with parameter. Here's the code, hopefully somebody can explain the problem to me because I'm completely baffled...
Here's my header file: BankAcct.h
public ref class BankAcct
{
private:
int money;
public:
BankAcct();
BankAcct(int);
void Deposit(int);
void GetBalance(int&);
};
And my definition file: BankAcct.cpp
#include "StdAfx.h"
#include "BankAcct.h"
BankAcct::BankAcct()
{
money = 0;
}
BankAcct::BankAcct(int startAmt)
{
money = startAmt;
}
void BankAcct::Deposit(int depAmt)
{
money += depAmt;
}
void BankAcct::GetBalance(int& balance)
{
balance = money;
}
And finally my main form. Won't copy the whole thing, of course, but I'm trying to declare the new bank account object, and start it with a balance of say $50.
private:
BankAcct myAccount(50); //does not work! WHY??
//private:
//BankAcct myAccount; //works
then in the form constructor my code is this:
public:
frmBank(void)
{
InitializeComponent();
int bal;
myAccount.GetBalance(bal);
lblBankBalance->Text += Convert::ToString(bal);
}
I've included the BankAcct.h file at the top of my frmBank.h, what else am I doing wrong here? It works great if I use the default constructor (the one that starts the bank balance at zero). I get the following error messages:
error C2059: syntax error: 'constant'
and
error C2228: left of '.GetBalance' must have class/struct/union
Thank you for any and all help on this one!!
C#-style initialization does not work in C++. You need to put initializers in the initialization section of your constructor (i.e. between : and the opening brace { of the constructor:
public:
MyForm() : myAccount(50) {
// Your constructor
}
private:
BankAcct myAccount;
The way you have it now, myAccount is not defined as BankAcct, so calls of GetBalance do not compile either.
One easy workaround:
private:
BankAcct *myAccount; // Make this a pointer
... then ...
frmBank(void)
{
InitializeComponent();
myAccount = new BankAcct(50);
int bal = myAccount->GetBalance(bal);
lblBankBalance->Text += Convert::ToString(bal);
There are other approaches, too. But I think explicitly creating the "myAccount" object is arguably the clearest and simplest. IMHO...

Resources