Pages: 1 [2] 3   Go Down
Author Topic: How do you check the Length of an Array?  (Read 1980 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks like you need pedantic warnings:


I'm surprised that the compiler accepted that code.

I'm even more surprised what happens if you put a delay() in:
Code:
int i;
 
void setup()
{
  Serial.begin(9600);

  delay(50);
 
  i = millis();
  char global[i];   
  Serial.println(sizeof (global));

  int j = millis();
  char local[j];   
  Serial.println(sizeof (local));
}
void loop()
{
}

Quote from: sketch
49
52

Um, is it allowed to do that?
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
God Member
*****
Karma: 1
Posts: 547
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm suprised he had any RAM left after dimensioning an array to the return from millis().
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26296
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Why are you surprised?
Read the code again.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

C++ allows the size of stack based arrays to be dynamically stated (within the limits of stack size), but not resized.  It is valid code.
« Last Edit: February 04, 2012, 06:27:52 pm by lloyddean » Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 133
Posts: 6755
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Note, by the way, that you can not use the "sizeof" operator on arrays that have been passed to a function, since arrays are always passed  by reference (a pointer), and the size of a pointer is always 2.
Code:
int myarray[15];
void loop() {
  operate(myarray);
}
void operate(int arr[])
{
  Serial.print(sizeof(arr));
}
Will print "2."

Yes, there are reasons to support things like dynamically sized arrays, and arrays that contain information about their actual size.  But the C language doesn't support either one; it's a "primitive" language.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18794
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

C++ allows the size of stack based arrays to be dynamically stated (within the limits of stack size), but not resized.  It is valid code.

Well, you learn something new every day! I didn't know you could do that. smiley
Logged


UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, you learn something new every day! I didn't know you could do that. smiley

Nor me, although to be fair my 'C' is a few decades rusty and my C++ coding has all been pretty mundane stuff.

How is 'sizeof' worked out, then? I thought this was a compile time expression. Is the compiler creating an honorary class and using rtti, or something?
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, this whole conversation has gone well over my head in terms of what I can personally relate to, but I get that the general answer is that there isn't a simple function I can call that will return the number of indexes in an Array.

I'm glad people are having good discussion.

I'm sure I will have many more questions soon. Going from a very high level language such as PHP to ... whatever it is that Arduino uses (it's C right?) certainly has it's challenges. I'm only just beginning to realize how much processing power and ram a modern day web server actually has. Kind of boggles my mind!
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18794
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well this is interesting:

Code:
char array[i];
  f0: 2d b7        in r18, 0x3d ; 61
  f2: 3e b7        in r19, 0x3e ; 62
  f4: 26 1b        sub r18, r22
  f6: 37 0b        sbc r19, r23
  f8: 0f b6        in r0, 0x3f ; 63
  fa: f8 94        cli
  fc: 3e bf        out 0x3e, r19 ; 62
  fe: 0f be        out 0x3f, r0 ; 63

I bet you didn't realize that doing this:

Code:
char array[i];

... fiddled with the interrupt enable flag. smiley

Quote
How is 'sizeof' worked out, then? I thought this was a compile time expression. Is the compiler creating an honorary class and using rtti, or something?

Well the mind boggles a bit here too, but it appears that the compiler has saved the size of the array into temporary registers and passed that (in this case) to Serial.println().
Logged


SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 133
Posts: 6755
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
fiddled with the interrupt enable flag?
it has to, since it modifies the 16bit stack pointer one byte at a time:
Code:
  f0: 2d b7        in r18, 0x3d ; read stack pointer low byte
  f2: 3e b7        in r19, 0x3e ;  stack pointer high byte
  f4: 26 1b        sub r18, r22   ; create stack frame by
  f6: 37 0b        sbc r19, r23   ;   adjusting SP
  f8: 0f b6        in r0, 0x3f ; get status register
  fa: f8 94        cli       ;; don't want interrupts while writing SP
  fc: 3e bf        out 0x3e, r19 ; write new stack pointer
  fe: 0f be        out 0x3f, r0  ; restore interrupt status
I don't see the other half of the stack pointer being written, though !!??
Logged

Offline Offline
God Member
*****
Karma: 1
Posts: 547
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the case of dynamic arrays, to expand an existing populated array I must make a new array at the larger proportions then copy the old elements into the new, swap ppointers and destroy the old array?
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 56
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the case of dynamic arrays, to expand an existing populated array I must make a new array at the larger proportions then copy the old elements into the new, swap ppointers and destroy the old array?

Yes, that appears to be the case.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18794
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't see the other half of the stack pointer being written, though !!??

I left that line out:

Code:
  f8: 0f b6        in r0, 0x3f ; 63
  fa: f8 94        cli
  fc: 3e bf        out 0x3e, r19 ; 62
  fe: 0f be        out 0x3f, r0 ; 63
 100: 2d bf        out 0x3d, r18 ; 61

I presume it's done in this order because the processor guarantees to execute one instruction after setting the interrupt flag, so the instruction at 0x100 is executed before an interrupt. Although I can't see exactly where it says that in the datasheet. It says after a SEI it executes the next instruction, that's not quite the same as saying "after enabling interrupts with the SREG register".
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 485
Posts: 18794
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

In the case of dynamic arrays, to expand an existing populated array I must make a new array at the larger proportions then copy the old elements into the new, swap ppointers and destroy the old array?

Bear in mind these are local variables, not global ones. So you can't exactly do anything really useful with them (like, saving them from one function call to the next), and you can't destroy them as such.
Logged


Offline Offline
God Member
*****
Karma: 1
Posts: 547
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the case of:
Code:
void foo(int newBound)
    {
      static char arrElements[];
      .....
    }
In other languages the static keyword keeps the scope variable arrElements persistent across calls to foo, and of course is only accessible within foo. Is this also apply in C? If so then I could simply return the pointer to arrElement[] to use it globally.
Logged

Pages: 1 [2] 3   Go Up
Jump to: