Are variable declarations in inner code blocks permitted in the B programming language? - b-lang

For example, is the following snippet legal in B?
int main() {
auto i;
for (i = 0; i < 5; i++) {
auto x; // Is this legal?
}
}

Related

Coufused about using cpp to achieve selection sort

I tried to implement selection sorting in C++,when i encapsulate the swap function, the output shows a lot of zeros.But at beginning of array codes still work.When I replace swap function with the code in the comment, the output is correct.
I am so confused by this result, who can help me to solve it.
#include <iostream>
#include <string>
using namespace std;
template<class T>
int length(T& arr)
{
return sizeof(arr) / sizeof(arr[0]);
}
void swap(int& a, int& b)
{
a += b;
b = a - b;
a = a - b;
}
int main()
{
int array[] = { 2,2,2,2,6,56,9,4,6,7,3,2,1,55,1 };
int N = length(array);
for (int i = 0; i < N; i++)
{
int min = i; // index of min
for (int j = i + 1;j < N; j++)
{
if (array[j] < array[min]) min = j;
}
swap(array[i],array[min]);
// int temp = array[i];
// array[i] = array[min];
// array[min] = temp;
}
for (int i = 0; i < N; i++)
{
int showNum = array[i];
cout << showNum << " ";
}
return 0;
}
Problem is that your swap function do not work if a and b refer to same variable. When for example swap(array[i], array[i]) is called.
Note in such case, this lines: b = a - b; will set b to zero since a and b are same variable.
This happens when by a chance i array element is already in place.
offtopic:
Learn to split code into functions. Avoid putting lots of code in single function especially main. See example. This is more important the you think.
Your swap function is not doing what it is supposed to do. Just use this instead or fix your current swap.
void swap(int& a, int& b){
int temp = a;
a = b;
b = temp;
}

GCC optimalizations ignore for loop condition

so I wrote this code:
#include <iostream>
constexpr
int fibonacci (int n) {
int a = 0;
int b = 1;
for(auto i = 0; i < n; i++) {
b += a;
a = b - a;
}
return b;
}
template<int N, int (T)(int)>
struct array {
using type = decltype(T(0));
constexpr array() : arr() {
for (auto i = 0; i < N; ++i) {
arr[i] = T(i);
}
}
const type &operator[](int i) const { return arr[i]; }
private:
type arr[N];
};
int main() {
constexpr auto x = array<10, fibonacci>();
for (int i = 0; i < 11; i++) {
std::cout << i << " " << x[i] << std::endl;
}
}
And without optimizations it works as expected, prints 11 values with last one being random value. But as soon I move to -O2 I get randomly long list of numbers finished with crash and segmentation fault.
I checked this result on godbolt.org (https://godbolt.org/z/4MqjbPbxE) and it seems that it is not a problem in, for example, clang.
My question is, is this a bug in gcc? Why would optimizations remove/not check condition in for loop?
You are invoking undefined behavior by using out-of-range x[i].
Allocate one more to avoid out-of-range access.
In other words,
constexpr auto x = array<10, fibonacci>();
should be
constexpr auto x = array<11, fibonacci>();
Defining constant to avoid typo is better:
int main() {
constexpr int num = 11;
constexpr auto x = array<num, fibonacci>();
for (int i = 0; i < num; i++) {
std::cout << i << " " << x[i] << std::endl;
}
}
Fix checking index.
for (int i = 0; i < 10; i++) {

Using for loop inside declaration of variable

Can I use for loop inside declaration a variable?
int main() {
int a = {
int b = 0;
for (int i = 0; i < 5; i++) {
b += i;
}
return b;
};
printf("%d", a);
}
You can use a lambda:
int main() {
int a = []{
int b = 0;
for (int i = 0; i < 5; i++) {
b += i;
}
return b;
}();
printf("%d", a);
}
It's important to note that you have to immediately execute it otherwise you attempt to store the lambda. Therefore the extra () at the end.
If you intent to reuse the lambda for multiple instantiations, you can store it separately like this:
int main() {
auto doCalculation = []{
int b = 0;
for (int i = 0; i < 5; i++) {
b += i;
}
return b;
};
int a = doCalculation();
printf("%d", a);
}
If you need it in more than one scope, use a function instead.
actually has been prepared by C++ committee..
constexpr has many usefulness not yet exlpored
constexpr int b(int l) {
int b=0;
for (int i = 0; i < l; i++)
b += i;
return b;
}
int main() {
constexpr int a = b(5);
printf("%d", a);
}

c++ define variable inside if block for function scope

Background: I am working on developing several different controllers (over 10 or so) for a hardware which involves running the code in hard real-time under RTAI linux. I have implemented a class for the hardware with each controller as a separate member function of the class. I'm looking to pass the desired trajectory for the respective control variable to each of these control functions based on which controller is chosen. In addition, since there are several parameters for each controller and I am looking to quickly switch controllers without having to navigate through the entire code and changing parameters, I am looking to define all the control variables at one place and define them based on which controller I choose to run. Here is a minimum working example of what I am looking for.
I am looking to define variables based on if a condition is true or not as follows in C++:
int foo()
{
int i=0;
if(i==0)
{
int a=0;
float b=1;
double c=10;
}
elseif(i==1)
{
int e=0;
float f=1;
double g=10;
}
// Memory locked for hard real-time execution
// execute in hard real-time from here
while(some condition)
{
// 100's of lines of code
if(i==0)
{
a=a+1;
b=b*2;
c=c*4;
// 100's of lines of code
}
elseif(i==1)
{
e=e*e*e;
f=f*3;
g=g*10;
// 100's of lines of code
}
// 100's of lines of code
}
// stop execution in hard real-time
}
The above code gives error on execution as the scope of the variables defined in the if blocks is limited to the respective if block. Could anyone suggest a better way of handling this issue? What is the best practice in this context in C++?
In your case, you may simply use:
int foo()
{
int i = 0;
if (i == 0) {
int a = 0;
float b = 1;
double c = 10;
for(int j = 1; j < 10; j++) {
a = a + 1;
b = b * 2;
c = c * 4;
}
} else if (i == 1) {
int e = 0;
float f = 1;
double g = 10;
for(int j = 1; j < 10; j++) {
e = e * e * e;
f = f * 3;
g = g * 10;
}
}
}
or even better, create sub-functions
void foo0()
{
int a = 0;
float b = 1;
double c = 10;
for(int j = 1; j < 10; j++) {
a = a + 1;
b = b * 2;
c = c * 4;
}
}
void foo1()
{
//.. stuff with e, f, g
}
int foo()
{
int i = 0;
if (i == 0) {
foo0();
} else if (i == 1) {
foo1();
}
}

Why using inline function in c++ doesn't grow binary size?

I have written this code:
inline int a_plus_b_power2(int a, int b) {
return (a + b) * (a + b);
}
int main() {
for(int a = 0; a < 9999999999999; ++a)
for(int b = 0; b < 999999999999; ++b)
a_plus_b_power2(a, b);
return 0;
}
but why the binary of this program doesn't differ with this program:
inline int a_plus_b_power2(int a, int b) {
return (a + b) * (a + b);
}
int main() {
for(int a = 0; a < 9; ++a)
for(int b = 0; b < 9; ++b)
a_plus_b_power2(a, b);
return 0;
}
You are confusing function inlining with loop unrolling:
Loop unrolling means transforming
for (int i = 0; i < 4; i++)
a(i);
into
a(0); a(1); a(2); a(3);
while function inlining means transforming
void a(int i) { cout << i; }
for (int i = 0; i < 4; i++)
a(i);
into
for (int i = 0; i < 4; i++)
cout << i;
Compilers do have options to enable loop unrolling (look at -funroll-loops and related options for gcc), but unless you poke them really hard, most of them will be very reluctant to unroll 999999999999 iterations... (the resulting binary would be multiple terabytes).
Inlined functions are only "pasted" once per invocation.
In both your examples, the inlined function is only invoked once, although it is called many times.
I believe you want something like this:
for (unsigned int a = 0; a < 9; ++a)
{
for (unsigned int b = 0; b < 9; b+= 3) // Incremented by 3 because of 3 calls in loop.
{
a_plus_b_power_2(a, b + 0);
a_plus_b_power_2(a, b + 1);
a_plus_b_power_2(a, b + 2);
}
}
The above example may cause the compiler to paste the code inside your inline function 3 times within the loop and increase the size of the binary.
Note: turn off optimizations because optimizations may cause the compiler to convert the inline function into a standalone function inside the loop.