Here is my first C++14 code.
The code uses a function (a lambda function) whose argument is an auto.
To compile and run this code in Linux:
g++-5 -std=c++14 cpp14.cpp && ./a.out
Of course, you need to install g++-5 first in order to use C++14. In Ubuntu:
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install g++-5
Tuesday, June 28, 2016
When Lambda capture by reference goes wrong
Here is a code that demonstrates lambda capture by value vs reference:
Running this code would yield 4.
When line 10 is used instead of line 9, running this code yields 10 instead of 4.
Ideally, 4 should be returned as the remainder of 10 divided by 6. If line 10 is used, however, the lambda function created encloses a reference to the variable x which goes out of scope as soon as the function add_func() completes execution.
After add_func() is called, the lambda function stored inside the vector uses a reference to x which is no longer valid (x only exists while add_func() is being executed). Therefore, the lambda function uses a reference to a variable with undefined value. Calling the lambda function therefore will yield to undefined results.
Running this code would yield 4.
When line 10 is used instead of line 9, running this code yields 10 instead of 4.
Ideally, 4 should be returned as the remainder of 10 divided by 6. If line 10 is used, however, the lambda function created encloses a reference to the variable x which goes out of scope as soon as the function add_func() completes execution.
After add_func() is called, the lambda function stored inside the vector uses a reference to x which is no longer valid (x only exists while add_func() is being executed). Therefore, the lambda function uses a reference to a variable with undefined value. Calling the lambda function therefore will yield to undefined results.
Monday, June 27, 2016
Factorial via template metaprogramming
Here is an example implementation of factorial via template metaprogramming:
Saturday, June 25, 2016
When auto fails
Got this from the book "Effective modern C++" by Scott Meyers (2014).
The book recommends the use of auto instead of explicit types. He does warn against using auto when proxy classes are involved. One example is std::vector<bool>. Using the operator[] on a std::vector<bool> yields a std::vector<bool>::reference (a proxy class) instead of a simple bool.
Consider this example:
According to Meyers, std::vector<bool>::reference is a class (a proxy class) that contains a pointer to a word (probably a 32-bit or 64-bit memory location) that contains the boolean value. The class also contains the offset within the word to be able to locate the boolean value.
So in the example, in line 22, b is of type std::vector<bool>::reference which contains a pointer to some memory location. Note, however, that features() returns a temporary std::vector<bool> which goes out of scope as soon as line 22 finishes execution. Thus, after line 22 is executed, the word (memory location) which contains the boolean goes out of scope. The pointer within b then becomes a dangling pointer pointing to who knows what.
When the code is executed:
nonbonding@castor-ub:~/dnonbonding/tmp/auto$ g++ -std=c++11 c.cpp && ./a.out
0/100
The book recommends the use of auto instead of explicit types. He does warn against using auto when proxy classes are involved. One example is std::vector<bool>. Using the operator[] on a std::vector<bool> yields a std::vector<bool>::reference (a proxy class) instead of a simple bool.
Consider this example:
According to Meyers, std::vector<bool>::reference is a class (a proxy class) that contains a pointer to a word (probably a 32-bit or 64-bit memory location) that contains the boolean value. The class also contains the offset within the word to be able to locate the boolean value.
So in the example, in line 22, b is of type std::vector<bool>::reference which contains a pointer to some memory location. Note, however, that features() returns a temporary std::vector<bool> which goes out of scope as soon as line 22 finishes execution. Thus, after line 22 is executed, the word (memory location) which contains the boolean goes out of scope. The pointer within b then becomes a dangling pointer pointing to who knows what.
When the code is executed:
nonbonding@castor-ub:~/dnonbonding/tmp/auto$ g++ -std=c++11 c.cpp && ./a.out
0/100
If line 23 is executed instead of line 22:
nonbonding@castor-ub:~/dnonbonding/tmp/auto$ g++ -std=c++11 c.cpp && ./a.out
100/100
Meyers calls the style used in line 23 as "the explicitly typed initializer idiom".
std::move example
Here is an example of move semantics:
When line 24 is used:
nonbonding@castor-ub:~/dnonbonding/tmp/rvalue$ g++ -std=c++11 c.cpp && time ./a.out
200000000
200000000
real 0m31.475s
user 0m24.932s
sys 0m4.604s
When line 24 is used:
nonbonding@castor-ub:~/dnonbonding/tmp/rvalue$ g++ -std=c++11 c.cpp && time ./a.out
200000000
200000000
real 0m31.475s
user 0m24.932s
sys 0m4.604s
When line 25 is used instead of line 24:
nonbonding@castor-ub:~/dnonbonding/tmp/rvalue$ g++ -std=c++11 c.cpp && time ./a.out
200000000
0
real 0m17.334s
user 0m16.708s
sys 0m0.440s
Execution time was reduced by almost a half!
DL 256QAM
In LTE, downlink 256QAM is triggered by a handshake between the UE and the eNodeB. First the UE signifies it is capable of performing 256QAM by sending the RRC information element (IE) dl-256QAM-r12 to the eNodeB. Should the eNodeB choose to perform 256QAM, then it sends the RRC IE altCQI-Table-r12 to the UE.
altCQI-Table-r12 is sent through the RRC message CQI-ReportConfig-r1250 which is a "Need ON" optional message. "Need ON" means that no action should be done by the UE if the UE does not receive the message again, upon say, RRC reconfiguration.
So to trigger 256QAM in the downlink, first, the UE sends dl-256QAM-r12 to the eNB to signify it is capable of 256QAM. Then the eNodeB sends CQI-ReportConfig-r1250 containing altCQI-Table-12 to the UE.
In case of RRC reconfiguration, say during handover, and the eNodeB still desires to continue using 256QAM, then it need not send CQI-ReportConfig-r1250 anymore to the UE because of the "Need ON" condition. Remember "Need ON" means that if the IE is not sent again (during reconfiguration), then the UE should maintain the status quo: if it was previously configured to use 256QAM, then after reconfiguration, it should still use 256QAM.
If the UE was previously configured by the eNodeB to use 256QAM, and after reconfiguration, the eNB does not wish to continue to use 256QAM anymore, then the eNodeB has to send CQI-ReportConfig-r1250 with no altCQI-Table-r12. The eNodeB has to send CQI-ReportConfig-r1250 with altCQI-Table-r12 missing or absent, in order to turn off 256QAM. If it does not send CQI-ReportConfig-r1250, then it means that the eNodeB still wishes to continue using 256QAM (remember "Need ON").
See 3GPP TS36.331 for more details.
altCQI-Table-r12 is sent through the RRC message CQI-ReportConfig-r1250 which is a "Need ON" optional message. "Need ON" means that no action should be done by the UE if the UE does not receive the message again, upon say, RRC reconfiguration.
So to trigger 256QAM in the downlink, first, the UE sends dl-256QAM-r12 to the eNB to signify it is capable of 256QAM. Then the eNodeB sends CQI-ReportConfig-r1250 containing altCQI-Table-12 to the UE.
In case of RRC reconfiguration, say during handover, and the eNodeB still desires to continue using 256QAM, then it need not send CQI-ReportConfig-r1250 anymore to the UE because of the "Need ON" condition. Remember "Need ON" means that if the IE is not sent again (during reconfiguration), then the UE should maintain the status quo: if it was previously configured to use 256QAM, then after reconfiguration, it should still use 256QAM.
If the UE was previously configured by the eNodeB to use 256QAM, and after reconfiguration, the eNB does not wish to continue to use 256QAM anymore, then the eNodeB has to send CQI-ReportConfig-r1250 with no altCQI-Table-r12. The eNodeB has to send CQI-ReportConfig-r1250 with altCQI-Table-r12 missing or absent, in order to turn off 256QAM. If it does not send CQI-ReportConfig-r1250, then it means that the eNodeB still wishes to continue using 256QAM (remember "Need ON").
See 3GPP TS36.331 for more details.
boost::any
My first attempt at using boost::any.
Adapted this code from here:
Adapted this code from here:
Here's the sample output:
nonbonding@castor-ub:~/dnonbonding/tmp/any$ g++ -std=c++11 -I/home/nonbonding/dnonbonding/bin/boost_1_60_0 c.cpp
nonbonding@castor-ub:~/dnonbonding/tmp/any$ ./a.out
#empty == 1
#int == 2
#const char * == 2
#string == 1
1 hello (empty) there world 6
nonbonding@castor-ub:~/dnonbonding/tmp/any$
Subscribe to:
Posts (Atom)