Is it possible to convert integral_constant to hana::string - boost-hana

I would like to be able to generate a compile-time string that contains a compile-time integer, like this. Is it possible?
I know I can insert a single elements to the boost::string using fold_left, but I would like to add a decimal representation of the integer. Is there any library that allows that?
#include <boost/hana/string.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/plus.hpp>
namespace hana = boost::hana;
using namespace hana::literals;
int main() {
auto a = "test_nr_"_s;
auto b = 42_c;
auto c = a + b;
};
I expect to get a way to make c equal "test_nr_42"_s.

Unfortunately, Boost.Hana does not support converting an integer to hana::string, and implicit conversions are right out.
However, with a little constexpr and a just sprinkle of EuclideanRing we can make our own conversion function like this:
#define BOOST_HANA_CONFIG_ENABLE_STRING_UDL
#include <boost/hana.hpp>
namespace hana = boost::hana;
using namespace hana::literals;
constexpr size_t get_magnitude(size_t num) {
unsigned i = 0;
while (num > 0) {
num /= 10;
++i;
}
return i;
}
template <typename X, size_t ...i>
constexpr auto to_string(X x,
std::index_sequence<i...>) {
constexpr size_t mag = get_magnitude(X::value);
return hana::string<
(x / hana::power(hana::size_c<10>,
hana::size_c<mag - i - 1>) % hana::size_c<10>
+ hana::size_c<48>)...>{};
}
template <typename X>
constexpr auto to_string(X x) {
return to_string(hana::size_c<static_cast<size_t>(X::value)>,
std::make_index_sequence<get_magnitude(X::value)>());
}
int main() {
auto a = "test_nr_"_s;
auto b = 42_c;
auto c = a + to_string(b);
static_assert(c == "test_nr_42"_s, "");
}

Related

How to define and execute an array of functions on Sycl+openCL+DPCPP

In my program, I defined an array of functions
#include <CL/sycl.hpp>
#include <iostream>
#include <tbb/tbb.h>
#include <tbb/parallel_for.h>
#include <vector>
#include <string>
#include <queue>
#include<tbb/blocked_range.h>
#include <tbb/global_control.h>
#include <chrono>
using namespace tbb;
template<class Tin, class Tout, class Function>
class Map {
private:
Function fun;
public:
Map() {}
Map(Function f):fun(f) {}
std::vector<Tout> operator()(bool use_tbb, std::vector<Tin>& v) {
std::vector<Tout> r(v.size());
if(use_tbb){
// Start measuring time
auto begin = std::chrono::high_resolution_clock::now();
tbb::parallel_for(tbb::blocked_range<Tin>(0, v.size()),
[&](tbb::blocked_range<Tin> t) {
for (int index = t.begin(); index < t.end(); ++index){
r[index] = fun(v[index]);
}
});
// Stop measuring time and calculate the elapsed time
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
printf("Time measured: %.3f seconds.\n", elapsed.count() * 1e-9);
return r;
} else {
sycl::queue gpuQueue{sycl::gpu_selector()};
sycl::range<1> n_item{v.size()};
sycl::buffer<Tin, 1> in_buffer(&v[0], n_item);
sycl::buffer<Tout, 1> out_buffer(&r[0], n_item);
gpuQueue.submit([&](sycl::handler& h){
//local copy of fun
auto f = fun;
sycl::accessor in_accessor(in_buffer, h, sycl::read_only);
sycl::accessor out_accessor(out_buffer, h, sycl::write_only);
h.parallel_for(n_item, [=](sycl::id<1> index) {
out_accessor[index] = f(in_accessor[index]);
});
}).wait();
}
return r;
}
};
template<class Tin, class Tout, class Function>
Map<Tin, Tout, Function> make_map(Function f) { return Map<Tin, Tout, Function>(f);}
typedef int(*func)(int x);
//define different functions
auto function = [](int x){ return x; };
auto functionTimesTwo = [](int x){ return (x*2); };
auto functionDivideByTwo = [](int x){ return (x/2); };
auto lambdaFunction = [](int x){return (++x);};
int main(int argc, char *argv[]) {
std::vector<int> v = {1,2,3,4,5,6,7,8,9};
//auto f = [](int x){return (++x);};
//Array of functions
func functions[] =
{
function,
functionTimesTwo,
functionDivideByTwo,
lambdaFunction
};
for(int i = 0; i< sizeof(functions); i++){
auto m1 = make_map<int, int>(functions[i]);
//auto m1 = make_map<int, int>(f);
std::vector<int> r = m1(true, v);
//print the result
for(auto &e:r) {
std::cout << e << " ";
}
}
return 0;
}
instead of each time defining a function, I am interested in defining an array of functions and then execute it in my program. But in the part of SYCL for executing on GPU, I have an error and I do not know how to fix it.
The ERROR:
SYCL kernel cannot call through a function pointer
In particular, SYCL device code, as defined by this specification, does not support virtual function calls, function pointers in general, exceptions, runtime type information or the full set of C++ libraries that may depend on these features or on features of a particular host compiler. Nevertheless, these basic restrictions can be relieved by some specific Khronos or vendor extensions.
As per the sycl 2020 specification, No function pointers are allowed to be called in a SYCL kernel or any functions called by the kernel.
Please refer https://www.khronos.org/registry/SYCL/specs/sycl-2020/html/sycl-2020.html#introduction

How does one use qsort to sort a char containing pathnames/files based on their bytes?

I basically wrote a code in which I take two command line arguments one being the type of file that I want to search in my directory and they other being the amount I want(which is not implemented yet, but I can fix that)
The code is like so:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define sizeFileName 500
#define filesMax 5000
int cmpfunc( const void *a, const void *b) {
return *(char*)a + *(char*)b;
}
int main( int argc, char ** argv) {
FILE * fp = popen( "find . -type f", "r");
char * type = argv[1];
char * extension = ".";
char* tExtension;
tExtension = malloc(strlen(type)+1+4);
strcpy(tExtension, extension);
strcat(tExtension, type);
// printf("%s\n",tExtension);
int amount = atoi(argv[2]);
//printf("%d\n",amount);
char buff[sizeFileName];
int nFiles = 0;
char * files[filesMax];
while(fgets(buff,sizeFileName,fp)) {
int leng = strlen(buff) - 1;
if (strncmp(buff + leng - 4, tExtension, 4) == 0){
files[nFiles] = strndup(buff,leng);
//printf("\t%s\n", files[nFiles]);
nFiles ++;
}
}
fclose(fp);
printf("Found %d files\n", nFiles);
long long totalBytes = 0;
struct stat st;
// sorting based on byte size from greatest to least
qsort(files, (size_t) strlen(files), (size_t) sizeof(char), cmpfunc);
for(int i = 0;i< nFiles; i ++) {
if(0!= stat(files[i],&st)){
perror("stat failed:");
exit(-1);
}
totalBytes += st.st_size;
printf("%s : %ld\n",files[i],st.st_size);
}
printf("Total size: %lld\n", totalBytes);
// clean up
for(int i = 0; i < nFiles ; i ++ ) {
free(files[i]);
}
return 0;
}
So far I have every section set up properly, upon running the code say $./find ini 5, it would print out all the ini files followed by their byte size(it's currently ignore the 5). However, for the qsort(), I'm not exactly sure how I would sort the contents of char * files as while it holds the pathnames, I had to use stat to get the byte sizes, how would I print out a sorted version of my print statements featuring the first statement being the most bytes and finishes at the least bytes?
If we suppose your input is valid, your question could be simplified with:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define filesMax 5000
int cmpfunc(const void const *a, const void *b) { return *(char *)a + *(char *)b; }
int main(void) {
int nFiles = 4;
char *files[filesMax] = {"amazing", "hello", "this is a file", "I'm a bad file"};
qsort(files, strlen(files), sizeof(char), cmpfunc);
for (int i = 0; i < nFiles;; i++) {
printf("%s\n", files[i]);
}
}
If you compile with warning that give you:
source_file.c:11:23: warning: incompatible pointer types passing 'char *[5000]' to parameter of type 'const char *' [-Wincompatible-pointer-types]
qsort(files, strlen(files), sizeof(char), cmpfunc);
^~~~~
qsort() expect the size of your array (or in your case a subsize) and it's also expect the size of one element of your array. In both you wrongly give it to it. Also, your compare function doesn't compare anything, you are currently adding the first bytes of both pointer of char, that doesn't make a lot of sense.
To fix your code you must write:
qsort(files, nFiles, sizeof *files, &cmpfunc);
and also fix your compare function:
int cmpfunc_aux(char * const *a, char * const *b) { return strcmp(*a, *b); }
int cmpfunc(void const *a, void const *b) { return cmpfunc_aux(a, b); }
also size should be of type size_t:
size_t nFiles = 0;
Don't forget that all informations about how to use a function are write in their doc.
how would I print out a sorted version of my print statements featuring the first statement being the most bytes and finishes at the least bytes?
Your code don't show any clue that your are trying to do that, you are currently storing name file and only that. How do you expect sort your file with an information you didn't acquired ?
However, that simple create a struct that contain both file name and size, acquire information needed to sort it and sort it:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <inttypes.h>
struct file {
off_t size;
char *name;
};
int cmpfunc_aux(struct file const *a, struct file const *b) {
if (a->size > b->size) {
return -1;
} else if (a->size < b->size) {
return 1;
} else {
return 0;
}
}
int cmpfunc(void const *a, void const *b) { return cmpfunc_aux(a, b); }
#define filesMax 5000
int main(void) {
size_t nFiles = 4;
struct file files[filesMax] = {{42, "amazing"},
{21, "hello"},
{168, "this is a file"},
{84, "I'm a bad file"}};
qsort(files, nFiles, sizeof *files, &cmpfunc);
for (size_t i = 0; i < nFiles; i++) {
printf("%s, %" PRId64 "\n", files[i].name, (intmax_t)files[i].size);
}
}
The function cmpfunc() provided adds the first character of each string, and that's not a proper comparison function (it should give a opposite sign value when you switch the parameters, e.g. if "a" and "b" are the strings to compare, it adds the first two characters of both strings, giving 97+98 == 195, which is positive on unsigned chars, then calling with "b" and "a" should give a negative number (and it again gives you 98 + 97 == 195), more on, it always gives the same result ---even with signed chars--- so it cannot be used as a sorting comparator)
As you are comparing strings, why not to use the standard library function strcmp(3) which is a valid comparison function? It gives a negative number if first string is less lexicographically than the second, 0 if both are equal, and positive if first is greater lexicographically than the second.
if your function has to check (and sort) by the lenght of the filenames, then you can define it as:
int cmpfunc(char *a, char *b) /* yes, you can define parameters as char * */
{
return strlen(a) - strlen(b);
}
or, first based on file length, then lexicographically:
int cmpfunc(char *a, char *b)
{
int la = strlen(a), lb = strlen(b);
if (la != lb) return la - lb;
/* la == lb, so we must check lexicographycally */
return strcmp(a, b);
}
Now, to continue helping you, I need to know why do you need to sort anything, as you say that you want to search a directory for a file, where does the sorting take place in the problem?

timerfd mysteriously set int to 0 when read()

I am doing an timerfd hello world in ubuntu 14.04, but got a strange situation: the int count is reset after read timerfd but uint64_int not.
int main(int agrc, char **argv) {
unsigned int heartbeat_interval = 1;
struct itimerspec next_timer;
struct timespec now;
if (clock_gettime(CLOCK_REALTIME, &now) == -1)
err_sys((WHERE + std::string("timer error")).c_str());
next_timer.it_value.tv_sec = now.tv_sec;
next_timer.it_value.tv_nsec = 0;
next_timer.it_interval.tv_sec = heartbeat_interval;
next_timer.it_interval.tv_nsec = 0;
int timefd = timerfd_create(CLOCK_REALTIME, 0);
if (timerfd_settime(timefd, TFD_TIMER_ABSTIME, &next_timer, NULL) == -1) {
err_sys((WHERE).c_str());
}
uint64_t s;
int exp;
int count = 1;
uint64_t count1=0;
while (1) {
s = read(timefd, &exp, sizeof(uint64_t));
if (s != sizeof(uint64_t)) {
err_sys((WHERE).c_str());
}
}
}
int exp;
^^^
s = read(timefd, &exp, sizeof(uint64_t));
^^^ ^^^^^^^^
Unless your int and uint64_t types are the same size, this is a very bad idea. What's most likely happening is that the 64 bits you're reading are overwriting exp and whatever else happens to be next to it on the stack.
Actually, even if they are the same size, it's a bad idea. What you should have is something like:
s = read(timefd, &exp, sizeof(exp));
That way, you're guaranteed to never overwrite the data and your next line would catch the problem for you:
if (s != sizeof(uint64_t)) {
It won't solve the problem that an unsigned integral type and an integral type will be treated differently but you can fix that just by using the right type for exp.

Sizeof pointer of pointer in C [duplicate]

First off, here is some code:
int main()
{
int days[] = {1,2,3,4,5};
int *ptr = days;
printf("%u\n", sizeof(days));
printf("%u\n", sizeof(ptr));
return 0;
}
Is there a way to find out the size of the array that ptr is pointing to (instead of just giving its size, which is four bytes on a 32-bit system)?
No, you can't. The compiler doesn't know what the pointer is pointing to. There are tricks, like ending the array with a known out-of-band value and then counting the size up until that value, but that's not using sizeof().
Another trick is the one mentioned by Zan, which is to stash the size somewhere. For example, if you're dynamically allocating the array, allocate a block one int bigger than the one you need, stash the size in the first int, and return ptr+1 as the pointer to the array. When you need the size, decrement the pointer and peek at the stashed value. Just remember to free the whole block starting from the beginning, and not just the array.
The answer is, "No."
What C programmers do is store the size of the array somewhere. It can be part of a structure, or the programmer can cheat a bit and malloc() more memory than requested in order to store a length value before the start of the array.
For dynamic arrays (malloc or C++ new) you need to store the size of the array as mentioned by others or perhaps build an array manager structure which handles add, remove, count, etc. Unfortunately C doesn't do this nearly as well as C++ since you basically have to build it for each different array type you are storing which is cumbersome if you have multiple types of arrays that you need to manage.
For static arrays, such as the one in your example, there is a common macro used to get the size, but it is not recommended as it does not check if the parameter is really a static array. The macro is used in real code though, e.g. in the Linux kernel headers although it may be slightly different than the one below:
#if !defined(ARRAY_SIZE)
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
#endif
int main()
{
int days[] = {1,2,3,4,5};
int *ptr = days;
printf("%u\n", ARRAY_SIZE(days));
printf("%u\n", sizeof(ptr));
return 0;
}
You can google for reasons to be wary of macros like this. Be careful.
If possible, the C++ stdlib such as vector which is much safer and easier to use.
There is a clean solution with C++ templates, without using sizeof(). The following getSize() function returns the size of any static array:
#include <cstddef>
template<typename T, size_t SIZE>
size_t getSize(T (&)[SIZE]) {
return SIZE;
}
Here is an example with a foo_t structure:
#include <cstddef>
template<typename T, size_t SIZE>
size_t getSize(T (&)[SIZE]) {
return SIZE;
}
struct foo_t {
int ball;
};
int main()
{
foo_t foos3[] = {{1},{2},{3}};
foo_t foos5[] = {{1},{2},{3},{4},{5}};
printf("%u\n", getSize(foos3));
printf("%u\n", getSize(foos5));
return 0;
}
Output:
3
5
As all the correct answers have stated, you cannot get this information from the decayed pointer value of the array alone. If the decayed pointer is the argument received by the function, then the size of the originating array has to be provided in some other way for the function to come to know that size.
Here's a suggestion different from what has been provided thus far,that will work: Pass a pointer to the array instead. This suggestion is similar to the C++ style suggestions, except that C does not support templates or references:
#define ARRAY_SZ 10
void foo (int (*arr)[ARRAY_SZ]) {
printf("%u\n", (unsigned)sizeof(*arr)/sizeof(**arr));
}
But, this suggestion is kind of silly for your problem, since the function is defined to know exactly the size of the array that is passed in (hence, there is little need to use sizeof at all on the array). What it does do, though, is offer some type safety. It will prohibit you from passing in an array of an unwanted size.
int x[20];
int y[10];
foo(&x); /* error */
foo(&y); /* ok */
If the function is supposed to be able to operate on any size of array, then you will have to provide the size to the function as additional information.
For this specific example, yes, there is, IF you use typedefs (see below). Of course, if you do it this way, you're just as well off to use SIZEOF_DAYS, since you know what the pointer is pointing to.
If you have a (void *) pointer, as is returned by malloc() or the like, then, no, there is no way to determine what data structure the pointer is pointing to and thus, no way to determine its size.
#include <stdio.h>
#define NUM_DAYS 5
typedef int days_t[ NUM_DAYS ];
#define SIZEOF_DAYS ( sizeof( days_t ) )
int main() {
days_t days;
days_t *ptr = &days;
printf( "SIZEOF_DAYS: %u\n", SIZEOF_DAYS );
printf( "sizeof(days): %u\n", sizeof(days) );
printf( "sizeof(*ptr): %u\n", sizeof(*ptr) );
printf( "sizeof(ptr): %u\n", sizeof(ptr) );
return 0;
}
Output:
SIZEOF_DAYS: 20
sizeof(days): 20
sizeof(*ptr): 20
sizeof(ptr): 4
There is no magic solution. C is not a reflective language. Objects don't automatically know what they are.
But you have many choices:
Obviously, add a parameter
Wrap the call in a macro and automatically add a parameter
Use a more complex object. Define a structure which contains the dynamic array and also the size of the array. Then, pass the address of the structure.
You can do something like this:
int days[] = { /*length:*/5, /*values:*/ 1,2,3,4,5 };
int *ptr = days + 1;
printf("array length: %u\n", ptr[-1]);
return 0;
My solution to this problem is to save the length of the array into a struct Array as a meta-information about the array.
#include <stdio.h>
#include <stdlib.h>
struct Array
{
int length;
double *array;
};
typedef struct Array Array;
Array* NewArray(int length)
{
/* Allocate the memory for the struct Array */
Array *newArray = (Array*) malloc(sizeof(Array));
/* Insert only non-negative length's*/
newArray->length = (length > 0) ? length : 0;
newArray->array = (double*) malloc(length*sizeof(double));
return newArray;
}
void SetArray(Array *structure,int length,double* array)
{
structure->length = length;
structure->array = array;
}
void PrintArray(Array *structure)
{
if(structure->length > 0)
{
int i;
printf("length: %d\n", structure->length);
for (i = 0; i < structure->length; i++)
printf("%g\n", structure->array[i]);
}
else
printf("Empty Array. Length 0\n");
}
int main()
{
int i;
Array *negativeTest, *days = NewArray(5);
double moreDays[] = {1,2,3,4,5,6,7,8,9,10};
for (i = 0; i < days->length; i++)
days->array[i] = i+1;
PrintArray(days);
SetArray(days,10,moreDays);
PrintArray(days);
negativeTest = NewArray(-5);
PrintArray(negativeTest);
return 0;
}
But you have to care about set the right length of the array you want to store, because the is no way to check this length, like our friends massively explained.
This is how I personally do it in my code. I like to keep it as simple as possible while still able to get values that I need.
typedef struct intArr {
int size;
int* arr;
} intArr_t;
int main() {
intArr_t arr;
arr.size = 6;
arr.arr = (int*)malloc(sizeof(int) * arr.size);
for (size_t i = 0; i < arr.size; i++) {
arr.arr[i] = i * 10;
}
return 0;
}
No, you can't use sizeof(ptr) to find the size of array ptr is pointing to.
Though allocating extra memory(more than the size of array) will be helpful if you want to store the length in extra space.
int main()
{
int days[] = {1,2,3,4,5};
int *ptr = days;
printf("%u\n", sizeof(days));
printf("%u\n", sizeof(ptr));
return 0;
}
Size of days[] is 20 which is no of elements * size of it's data type.
While the size of pointer is 4 no matter what it is pointing to.
Because a pointer points to other element by storing it's address.
In strings there is a '\0' character at the end so the length of the string can be gotten using functions like strlen. The problem with an integer array, for example, is that you can't use any value as an end value so one possible solution is to address the array and use as an end value the NULL pointer.
#include <stdio.h>
/* the following function will produce the warning:
* ‘sizeof’ on array function parameter ‘a’ will
* return size of ‘int *’ [-Wsizeof-array-argument]
*/
void foo( int a[] )
{
printf( "%lu\n", sizeof a );
}
/* so we have to implement something else one possible
* idea is to use the NULL pointer as a control value
* the same way '\0' is used in strings but this way
* the pointer passed to a function should address pointers
* so the actual implementation of an array type will
* be a pointer to pointer
*/
typedef char * type_t; /* line 18 */
typedef type_t ** array_t;
int main( void )
{
array_t initialize( int, ... );
/* initialize an array with four values "foo", "bar", "baz", "foobar"
* if one wants to use integers rather than strings than in the typedef
* declaration at line 18 the char * type should be changed with int
* and in the format used for printing the array values
* at line 45 and 51 "%s" should be changed with "%i"
*/
array_t array = initialize( 4, "foo", "bar", "baz", "foobar" );
int size( array_t );
/* print array size */
printf( "size %i:\n", size( array ));
void aprint( char *, array_t );
/* print array values */
aprint( "%s\n", array ); /* line 45 */
type_t getval( array_t, int );
/* print an indexed value */
int i = 2;
type_t val = getval( array, i );
printf( "%i: %s\n", i, val ); /* line 51 */
void delete( array_t );
/* free some space */
delete( array );
return 0;
}
/* the output of the program should be:
* size 4:
* foo
* bar
* baz
* foobar
* 2: baz
*/
#include <stdarg.h>
#include <stdlib.h>
array_t initialize( int n, ... )
{
/* here we store the array values */
type_t *v = (type_t *) malloc( sizeof( type_t ) * n );
va_list ap;
va_start( ap, n );
int j;
for ( j = 0; j < n; j++ )
v[j] = va_arg( ap, type_t );
va_end( ap );
/* the actual array will hold the addresses of those
* values plus a NULL pointer
*/
array_t a = (array_t) malloc( sizeof( type_t *) * ( n + 1 ));
a[n] = NULL;
for ( j = 0; j < n; j++ )
a[j] = v + j;
return a;
}
int size( array_t a )
{
int n = 0;
while ( *a++ != NULL )
n++;
return n;
}
void aprint( char *fmt, array_t a )
{
while ( *a != NULL )
printf( fmt, **a++ );
}
type_t getval( array_t a, int i )
{
return *a[i];
}
void delete( array_t a )
{
free( *a );
free( a );
}
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#define array(type) struct { size_t size; type elem[0]; }
void *array_new(int esize, int ecnt)
{
size_t *a = (size_t *)malloc(esize*ecnt+sizeof(size_t));
if (a) *a = ecnt;
return a;
}
#define array_new(type, count) array_new(sizeof(type),count)
#define array_delete free
#define array_foreach(type, e, arr) \
for (type *e = (arr)->elem; e < (arr)->size + (arr)->elem; ++e)
int main(int argc, char const *argv[])
{
array(int) *iarr = array_new(int, 10);
array(float) *farr = array_new(float, 10);
array(double) *darr = array_new(double, 10);
array(char) *carr = array_new(char, 11);
for (int i = 0; i < iarr->size; ++i) {
iarr->elem[i] = i;
farr->elem[i] = i*1.0f;
darr->elem[i] = i*1.0;
carr->elem[i] = i+'0';
}
array_foreach(int, e, iarr) {
printf("%d ", *e);
}
array_foreach(float, e, farr) {
printf("%.0f ", *e);
}
array_foreach(double, e, darr) {
printf("%.0lf ", *e);
}
carr->elem[carr->size-1] = '\0';
printf("%s\n", carr->elem);
return 0;
}
#define array_size 10
struct {
int16 size;
int16 array[array_size];
int16 property1[(array_size/16)+1]
int16 property2[(array_size/16)+1]
} array1 = {array_size, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
#undef array_size
array_size is passing to the size variable:
#define array_size 30
struct {
int16 size;
int16 array[array_size];
int16 property1[(array_size/16)+1]
int16 property2[(array_size/16)+1]
} array2 = {array_size};
#undef array_size
Usage is:
void main() {
int16 size = array1.size;
for (int i=0; i!=size; i++) {
array1.array[i] *= 2;
}
}
Most implementations will have a function that tells you the reserved size for objects allocated with malloc() or calloc(), for example GNU has malloc_usable_size()
However, this will return the size of the reversed block, which can be larger than the value given to malloc()/realloc().
There is a popular macro, which you can define for finding number of elements in the array (Microsoft CRT even provides it OOB with name _countof):
#define countof(x) (sizeof(x)/sizeof((x)[0]))
Then you can write:
int my_array[] = { ... some elements ... };
printf("%zu", countof(my_array)); // 'z' is correct type specifier for size_t

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