Show Posts
Pages: 1 2 3 [4] 5 6 ... 121
46  Using Arduino / Programming Questions / Re: Array Basics (sizeof) on: April 08, 2014, 02:26:06 am
And just to satisfy your demands here is function that takes a reference to any size array smiley

Code:
template< typename T, size_t N >  void Foo( T (&t)[N] ){
    Serial.write( t, N );
  }

And the pointer version
Code:
template< typename T, size_t N >  void Foo( T (*t)[N] ){
    Serial.write( *t, N );
  }

And if you look closely there is no need for sizeof to get the length.
47  Using Arduino / Programming Questions / Re: Array Basics (sizeof) on: April 08, 2014, 02:22:20 am
Quote
I showed clearly how to pass a pointer to an array and get the correct size using sizeof.
Code:
void Foo( arr_t *arrp ){
But that's not a pointer to an array; it's a pointer to a PARTICULAR SIZE of array.

There is no other definition of an array. The last index must always be sized.
48  Using Arduino / Programming Questions / Re: Controlling How a Library Compiles From Within a Project on: April 08, 2014, 02:07:47 am
None of this is addressing the OP's basic issue.

I agree with him,  I have had the same issues.   Unfortunately,  I think this is an inherent weakness of the Arduino IDE scheme.  perhaps a necessary and reasonable one in the interests of perceived "simplicity" and the inherent project scale limitations of microcontrollers.

Well actually as I pointed out, using a template design would allow selective compiling of components or debugging. And tgsuperspec pointed out how defines could select what to use in the header file. Wandered a bit off topic, however there are solutions to investigate. And neither are out of reach using the IDE.
49  Using Arduino / Programming Questions / Re: Array Basics (sizeof) on: April 08, 2014, 01:57:06 am
But in that situation, the size is known at compile time - it is know to be: sizeof(int)*n - of course it is known, otherwise it wouldn't be able to do malloc() for the array. Clearly during execution it has to do that multiplication.
n isn't known at compile time, only the sizeof int. Also its stored on the stack.

Code:
typedef int arr_t[ 10 ];
And that one is definitely known at compile time as sizeof(arr_t) is a type. Doing that is no different from passing an array to a function defined as:
void someFunc (int array[10]);

Yup, thats what I was showing.

In fact if you were to do this the size ceases to be known:
Code:
void someOtherFunc(int* arr){
  sizeof(arr); //=sizeof(pointer)
}
arr_t array = {1,2,3,4,5,6,7,8,9,0};
someOtherFunc((int*)array_t);

Yup, thats exactly what I've pointed out. int*arr is not the array and never will be, it only holds the address of the first element.
I showed clearly above how to pass a pointer to an array and get the correct size using sizeof.

Code:
void Foo( arr_t *arrp ){
 
  Serial.println( sizeof( *arrp ) / sizeof( **arrp ) );
}
50  Using Arduino / Programming Questions / Re: Library and array on: April 07, 2014, 11:34:57 pm
Ok, I think I understand.

The simplest way is to pass a pointer and length. Then you can use those bits of info to access the values.

Code:
//A library
class lib{
  public:
    //Constructor with initializer list.
    lib( char *ptr, int len ) : ptr( ptr ), len( len ) {}

    void Foo(){

      for( int idx = 0 ; idx < len ; ++idx ){

        Serial.println( ptr[ idx ] );
      }
    }

  protected:
    char *ptr;
    int len;
};

Code:
//In IDE
char array[ 5 ];

lib l( array, 5 ); //Pass pointer to first element & length

l.Foo(); //Foo uses a pointer passed into the constructor.
51  Using Arduino / Programming Questions / Re: Array Basics (sizeof) on: April 07, 2014, 10:45:37 pm
Quote
If you dereference a real pointer to an array, you can get the size using sizeof.
Only if it's a compile-time constant, right?
(and, are you sure?  I though ((sizeof array)/sizeof(*array)) was one of those tricks for finding the number of elements in an array...)


No, its not required to be a compile time constant for arrays.
Code:
void someFunc( int n ){
  
  int arr[ n ];
  Serial.println( sizeof( arr ) / sizeof( *arr ) );
}
//...
someFunc( random( 1, 30 ) );

I think I know what people are misunderstanding here, I'll fill in a few gaps.

Arrays are not lists of values based on a type, that is what their internal representation is. Arrays are actual types too. E.g. I can create a typedef of an array.

Code:
typedef int arr_t[ 10 ];

Not only can I create variables of this type:
Code:
arr_t arr = { 1,2,3,4,5,6,7,8,9,0 };

I can use it just like every other type.
Code:
void Foo( arr_t *arrp ){
  
  Serial.println( sizeof( *arrp ) / sizeof( **arrp ) );
}
//...
Foo( &arr );

A more practical method is to use a reference to avoid dereferencing the array.

Code:
void Foo( arr_t &ref ){
  Serial.println( sizeof( ref ) / sizeof( *ref ) );
}
//...
Foo( arr );

And finally, unknown to many, you can actually return arrays using their pointer or reference.
Code:
typedef int arr_t[10];
arr_t &Foo( arr_t &ref ); //Forward dec to stop IDE moaning

arr_t arr = { 1,2,3,4,5,6,7,8,9,0 };

arr_t &Foo( arr_t &ref ){
  Serial.println( sizeof( ref ) / sizeof( *ref ) );
  return ref;
}

void setup() {

  Serial.begin( 9600 );
  arr_t &ret = Foo( arr );
}

void loop(){}

I'm writing an FAQ on this topic on my site ( unfinished ), however this is a basic run down.
52  Using Arduino / Programming Questions / Re: Array Basics (sizeof) on: April 07, 2014, 10:15:19 pm
Not quite.

If you dereference a real pointer to an array, you can get the size using sizeof.

If you dereference the pointer to the first element, you get... well the first element.
53  Using Arduino / Programming Questions / Re: Array Basics (sizeof) on: April 07, 2014, 10:05:34 pm
@econjack,

Here is an excerpt straight out of the ISO C++ standard. Seriously I'm not trying to BS you.

Quote
4.2 Array-to-pointer conversion [conv.array]
1 An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to an rvalue
of type “pointer to T”. The result is a pointer to the first element of the array.
54  Using Arduino / Programming Questions / Re: Array Basics (sizeof) on: April 07, 2014, 09:57:15 pm
Quote
I was referring to the statement that ...it is not a reference to the array or a pointer to it..  We were talking about array names being passed to a function.

I'm not sure where you are getting confused, the function must accept an array type to accept an array. If for example you use a pointer to an int for the parameter, an int array will decay to a pointer of its first element and you are no longer dealing with an array. Which is what my post above explains. I'm sorry for using assignments as they seem to have been confusing. But the declarations can go straight into a function parameter list if you like.

You can use pointer arithmetic on a pointer, but that does not make it an array.


55  Using Arduino / Programming Questions / Re: Array Basics (sizeof) on: April 07, 2014, 09:37:44 pm
I disagree. You state:

...it is not a reference to the array or a pointer to it. Passing the array name without subscript operators decays the array type to a pointer of its first element, nothing to do with the original array.

Even your own quote says it's a pointer. If it has nothing to do with the original array, then why is the type of the pointer required as part of the parameter being passed?  The reason is because pointer operations are scaled to the data type being pointed to. Further, if it has nothing to do with the array, then why is the value passed the lvalue of the array? Indeed, it has everything to do with the array, otherwise the function wouldn't have a memory address to allow any operation to be performed on it. Indeed, if I pass in an array name and pass additional parameters for its length and rank, I can reference the array in a way that matches its original definition.

I'm sorry but you are making wild assumptions here, you can disagree, however you are wrong. It is a pointer to the first element, that is all. You can see this more clearly trying to apply your logic to a multidimensional array. I have showed you in my post above how to pass the actual array by reference or pointer, so I do not see how this is an argument.

Consider this.
Code:
int arr[][10] = {{1,2,3,4,5,6},{1,2,3,4,5,6}};

This is wrong, as using an array name without subscript operators does not return a pointer to the array.
Code: (wrong)
int **ptr = arr;

like I've already said it returns a pointer to its first element.
Code: (right)
int (*ptr)[10] = arr;

Also an int** of the same data structure would use more memory than the array!
56  Using Arduino / Programming Questions / Re: Controlling How a Library Compiles From Within a Project on: April 07, 2014, 09:18:01 pm
Sorry if you thought I was getting picky but Templates do not constitute true late binding, late binding realistically can only be truely implemented by virtual call tables as per ISO standards, the IDE will support virtual to some degree had it working, but now use Embedded X code far more satisfactory answer for larger complexprojects.

Also I did not say that pre processor would make library compilable differently, I said based on description of the problem he wanted to solve perhaps the whole library won't matter and he can use pre processor diective to compile specific aspects of his sketch only.

Well , in a run-time environment, yes, virtual calls are a form late binding, however so is using a non-virtual, non-member function pointer.
As for templates, they are only templates during compilation. Which also has late and early binding, which is a result of dependent & non-dependent types. The compiler is a Turing complete system which templates can exploit, and delaying the instantiation of an object is sometime necessary.
57  Using Arduino / Programming Questions / Re: Array Basics (sizeof) on: April 07, 2014, 08:37:58 pm
There is no way a function can know the size of the array because arrays are passed to a function by reference. That is, the function receives the memory address (lvalue) of where the array resides in memory. The only possible exception is a null terminated character array that's treated as a string.

That is incorrect, it is not a reference to the array or a pointer to it. Passing the array name without subscript operators decays the array type to a pointer of its first element, nothing to do with the original array. Which is why the sizeof operator does not work, as you are no longer dealing with an array.

Pass pointer to first element,
Code:
void someFunc( int *ptr ){
}

someFunc( array );

Pass array by reference:
Code:
void someFunc( int (&array)[10] ){
}
//OR
void someFunc( int array[10] ){
}

someFunc( array );

Pass array by pointer.
Code:
void someFunc( int (*array)[10] ){
}

someFunc( &array );
58  Using Arduino / Programming Questions / Re: Controlling How a Library Compiles From Within a Project on: April 07, 2014, 05:45:15 am
The only way you can cause changes in your library code ( .cpp ), based on your sketch code is to make the library dependent on the sketch, what is needed is late bound references to the library, which can be achieved using templates. I have used this method to allow custom settings for many different sketches.

 I'm writing an FAQ on the topic however its unfinished. I'll link to it when done.

If you are talking about using true late binding techniques with virtual calls etc.,  then the IDE is rubbish at resolving these properly since the IDE does all the mangling without the need for h files and creates one big cpp its no wonder virtual call tables give it a head ache. anyone who is not a seasons C++ programer needs to avoid the ideas behind Late binding stick with standard linkage.

My reply regarding Pre-Processor directives would solve the described requirement, yes the library itself would still be fully compiled, but the sketch app would only link to the aspects of library selected by the pre-porocessor directives. given the responces
to mine and other replies, this person is a newbie without a great deaL of experience in C so possibly reading a true book On C / C++ and programming in objects ...  rather than internet code snippets might prove useful.



Nope, I made no mention of virtual calls, I said templates. Virtual calls still require the whole implementation.

And no, pre-processor arguments do not work for selective compiling, have you tested it? The library .cpp files are compiled before your sketch is even able to provide its pre-processing. The directives will only affect the header file your sketch uses to compile, not the actual library.
59  Using Arduino / Programming Questions / Re: Controlling How a Library Compiles From Within a Project on: April 06, 2014, 09:44:49 pm
The only way you can cause changes in your library code ( .cpp ), based on your sketch code is to make the library dependent on the sketch, what is needed is late bound references to the library, which can be achieved using templates. I have used this method to allow custom settings for many different sketches.

 I'm writing an FAQ on the topic however its unfinished. I'll link to it when done.
60  Development / Other Software Development / Re: EthernetClient: while (!client) = infinite loop??? on: April 06, 2014, 09:23:17 am
That article is wrong, 'if(client)' checks the client port is not zero. As the example has not used client, it will always be zero.
I would simply remove the whole loop.

For the best Ethernet experience, I put a long delay before calling begin, DHCP was almost instant, whereas without a delay could take ages.
Pages: 1 2 3 [4] 5 6 ... 121