c++0x: Variadic Template technique - recursion

I am preparing myself for the defintion of user-defined literals with a Variadic Template
template<...>
unsigned operator "" _binary();
unsigned thirteen = 1101_binary;
GCC 4.7.0 does not support operator "" yet, but I can simulate this with a simple function until then.
Alas, my recursion is the wrong way around. I can not think of a nice way how I do not shift the rightmost values, but the leftmost:
template<char C> int _bin();
template<> int _bin<'1'>() { return 1; }
template<> int _bin<'0'>() { return 0; }
template<char C, char D, char... ES>
int _bin() {
return _bin<C>() | _bin<D,ES...>() << 1; // <-- WRONG!
}
which of course is not quite right:
int val13 = _bin<'1','1','0','1'>(); // <-- gives 10
because my recursion shifts the rightmost '1's farthest, and not the leftmost ones.
It is probably I tiny thing, but I just can not see it.
Can I correct the line _bin<C>() | _bin<D,ES...>() << 1;?
Or do I have to forward everything and turn it around everything afterwards (not nice)?
Or any other way that I can not see?
Update: I could not fold the recursion the other way around, but I discovered sizeof.... Works, but not perfect. Is there another way?
template<char C, char D, char... ES>
int _bin() {
return _bin<C>() << (sizeof...(ES)+1) | _bin<D,ES...>() ;
}

At any one step of the recursion you already know the rank of the leftmost digit.
template<char C> int _bin();
template<> int _bin<'1'>() { return 1; }
template<> int _bin<'0'>() { return 0; }
template<char C, char D, char... ES>
int _bin() {
return _bin<C>() << (1 + sizeof...(ES)) | _bin<D,ES...>();
}

Parameter packs are relatively inflexible, and you don't usually write algorithms directly in them. Variadic function templates are good for forwarding, but I'd get that packed into a more manageable tuple before trying to manipulate it.
Using a simple binary_string_value metafunction where the 1's place comes first, and a generic tuple_reverse metafunction, the pattern would be
template< char ... digit_pack >
constexpr unsigned long long _bin() {
typedef std::tuple< std::integral_constant< digit_pack - '0' > ... > digit_tuple;
return binary_string_value< typename tuple_reverse< digit_tuple >::type >::value;
}

One possibility would be using an accumulator:
template <char C>
int _binchar();
template<>
int _binchar<'0'>() { return 0; }
template<>
int _binchar<'1'>() { return 1; }
template<char C>
int _bin(int acc=0) {
return (acc*2 + _binchar<C>());
}
template<char C, char D, char... ES>
int _bin(int acc=0) {
return _bin<D, ES...>(acc*2 + _binchar<C>());
}

Related

Looking for Segmentation Fault in C script

Hi trying to learn C specifically how to use pointers.
I wrote this script to practice ideas I've learned, but it crashes with segmentation fault error.
Bit of research search suggests that I am trying to access something that I should not be accessing I think that is an uninitialized pointer but I can't find it.
#include <stdio.h>
struct IntItem {
struct IntItem* next;
int value;
};
struct IntList {
struct IntItem* head;
struct IntItem* tail;
};
void append_list(struct IntList* ls, int item){
struct IntItem* last = ls->tail;
struct IntItem addition = {NULL,item};
last->next = &addition;
ls->tail = &addition;
if (!ls->head) {
ls->head = &addition;
}
}
int sum(int x, int y){
return x + y;
}
int max(int x, int y){
return x*(x>y) + y*(y>x);
}
int reduce(struct IntList xs, int (*opy)(int, int)){
struct IntItem current = *xs.head;
int running = 0;
while (current.next) {
running = opy(running,current.value);
current = *current.next;
}
return running;
}
int main(void) {
struct IntList ls = {NULL, NULL};
printf("Start Script\n");
append_list(&ls, 1);
append_list(&ls, 2);
append_list(&ls, 3);
printf("List Complete\n");
printf("Sum: %i",reduce(ls,sum));
printf("Max: %i",reduce(ls,max));
return 0;
}
Hints:
When you call append_list(&ls, 1), then inside append_list, what is the value of last?
What does last->next = &addition do?
And for your next bug:
What happens to addition after append_list returns? What does that mean for pointers to it?

Correct Assignment for Pointers

I am shifting from Python to C so bit rusty on the semantics as well as coding habit. In Python everything is treated as an object and objects are passed to functions. This is not the case in C so I want to increment an integer using pointers. What is the correct assignment to do so. I want to do it the following way but have the assignments wrong:
#include <stdio.h>
int i = 24;
int increment(*i){
*i++;
return i;
}
int main() {
increment(&i);
printf("i = %d, i);
return 0;
}
I fixed your program:
#include <stdio.h>
int i = 24;
// changed from i to j in order to avoid confusion.
// note you could declare the return type as void instead
int increment(int *j){
(*j)++;
return *j;
}
int main() {
increment(&i);
printf("i = %d", i);
return 0;
}
Your main error was the missing int in the function's argument (also a missing " in the printf).
Also I would prefer using parentheses in expressions as *j++ and specify exactly the precedence like I did in (*j)++, because I want to increment the content of the variable in the 'j' location not to increment the pointer - meaning to point it on the next memory cell - and then use its content.

Frama-C: Get slice for C assert statement

Is there a way to use Frama-C's slicing plugin to compute slices for a specific C assert statement?
For example, given the following code:
int main() {
double a=3;
double b=4;
double c=123;
assert(b>=0);
double d=a/b;
c=a;
return 0;
}
I would like to get the following slice for assert(b>=0);:
int main() {
double b=4;
assert(b>=0);
return 0;
}
If you can rewrite your assert as an ACSL assertion, you can use option -slice-assert main.
int main() {
double a=3;
double b=4;
double c=123;
//# assert(b>=0);
double d=a/b;
c=a;
return 0;
}
(In this case, the division will also be removed, as it does not influence the assertion.)
void main(void)
{
double b;
b = (double)4;
/*# assert b ≥ 0; */ ;
return;
}
Alternatively, you can also slice on the calls to the assert function, using -slice-calls assert.
void main(void)
{
double b;
b = (double)4;
assert(b >= (double)0);
return;
}
If you want to slice on a particular assertion (if there are more than one in the function), you will have to use a slicing pragma, or the programmatic API (not recommended).

seg fault / pointer assistance

so i know the bases of programming, i have a decent amount of experience with java, but im learning C for school right now. I still dont completely understand the whole pointer aspect, which is what im sure caused the fault. This program works fine when run on my computer, but when i try and run it on my schools unix shell it gives me a seg fault. if someone could please explain to me why or how ive misused hte pointers, that would help me greatly.
//Matthew Gerton
//CS 222 - 002
//10/10/14
//HW Six
//libraries
#include<stdio.h>
#include<string.h>
#define max_Length 256
//prototypes
void decode(char *a, char *b);
void trimWhite(char *a);
void encode(char *a, char *b);
int main(void)
{
//character arrays
char coded[max_Length], decoded[max_Length];
//decode the sample phrase
char sample[] = {'P','H','H','W','D','W','C','R','R','F','D','Q','F','H','O','H','G','J',
'R','W','R','P','H','W','U','R','K','R','W','H','O','U','R','R','P','I','R','X','U'};
decode(sample, decoded);
//scans a user input string to decode, and decodes it
printf("\nPlease enter a phrase to decode: ");
gets(coded);
trimWhite(coded);
decode(coded, decoded);
//scans a user input phrase to encode
printf("\nPlease enter a phrase to encode: ");
gets(coded);
trimWhite(coded);
encode(coded, decoded);
}
//removes any spaces from the input
void trimWhite(char *a)
{
char temp[max_Length];
int z=0, y=0;
while(a[z]!='\0')
{
if(a[z]!=' ')
{
temp[y]=a[z];
y++;
}
z++;
}
temp[y] = '\0';
strcpy(a,temp);
}
//decodes any phrase
void decode(char *a, char *b)
{
int i=0,n;
memset(b, '\0', sizeof(b));
while(a[i]!='\0')
{
n=(int)a[i];
if(n<97)
n=n+32;
if(n<=99)
n=n+23;
else
n = n-3;
b[i]= (char) n;
i++;
}
b[i]='\0';
printf("Coded message: %s\n", a);
printf("Decoded message: %s\n", b);
}
//codes an input phrase
void encode(char *a, char *b)
{
int i=0,n;
memset(b, '\0', sizeof(b));
strcpy(b,a);
while(a[i]!='\0')
{
n=(int)a[i];
if(n<97)
a[i] = (char)(n+32);
if((n>120)
a[i] = (char)(n-23);
else
a[i] = (char)((n+3);
i++;
}
printf("Coded message: %s\n", a);
}
Your main problem is here:
char sample[] = {'P','H','H', /* snip */ ,'R','X','U'};
The sample[] array is not zero-terminated which may cause the decode() function to copy many more characters than intended, thus overwriting other variables. You need to explicitly add a terminating zero when using an initializer-list:
char sample[] = {'P','H','H', /* ... */ ,'R','X','U',0};
Or you can initialize the array using a string literal, which does include a terminating zero:
char sample[] = "PHHWDWCRRFDQFHOHGJRWRPHWURKRWHOURRPIRXU";
You should probably read "Why is the gets function dangerous".
...
void decode(char *a, char *b)
{
int i=0,n;
memset(b, '\0', sizeof(b));
Also note that the size of the array is lost when it is passed to a function. The function only receives a pointer to its first element. The memset() call above will only zero sizeof(char*) bytes (usually 4 or 8). This doesn't matter though because, as far as I can tell, you only need to zero the first byte. You could simply write:
b[0] = 0;

gcc: /home/jamie/aws/btree_int.c|28|error: request for member ‘btree_start’ in something not a structure or union|

This code:
#include <stdlib.h>
#include <stdio.h>
int j_btree_create (int fn_initial_nodes);
typedef struct {
int depth;
int value;
void *item;
void *left_pointer;
void *right_pointer;
} j_btree_node_int;
typedef struct {
int nodes;
int available_nodes;
int btree_extension;
} j_btree_descriptor_int;
int j_btree_create (int fn_initial_nodes) {
int *free_btree_node;
int loop_counter;
j_btree_descriptor_int *btree_start;
btree_start = (j_btree_descriptor_int *) malloc (((sizeof(j_btree_node_int) + sizeof(free_btree_node)) * fn_initial_nodes) + sizeof(j_btree_descriptor_int));
printf ("btree_start: " . btree_start);
/* *btree_start.nodes = fn_initial_nodes;
*btree_start.available_nodes = fn_initial_nodes;
*btree_start.extension = NULL; */
for (loop_counter = 0; loop_counter < fn_initial_nodes; loop_counter++) {
printf ("loop_test:" . loop_counter);
}
}
Produces this error:
/home/jamie/aws/btree_int.c||In function ‘j_btree_create’:|
/home/jamie/aws/btree_int.c|28|error: request for member ‘btree_start’ in something not a structure or union|
/home/jamie/aws/btree_int.c|33|error: request for member ‘loop_counter’ in something not a structure or union|
||=== Build finished: 2 errors, 0 warnings ===|
When compiled with CodeBlocks. I have not managed to find an exact answer to my problem (I have looked), does anyone know roughly what I am doing wrong? Probably more than one thing given I am fairly new to C.
printf ("btree_start: " . btree_start);
This is not how the things are done in c. There's no . concatenation operator and you do not concatenate strings (pointers to characters) and pointers to structures. If you want to print out the pointer, it's
printf("btree_start: %p\n",btree_start);
For the loop counter it's
printf("loop_test: %d",loop_counter);

Resources