filling remaining array elements with fixed value

Hi to all here

Using Codewarrior,GNU i want to declare an array in program memory like this:

const unsigned char my_array[8]={0xA,0xB,0xC,0xFF,0xFF,0xFF,0xFF,0xFF};

Is there any convenient way to do it if the array is 1024 elements wide?

Many thanks

Diego

Reply to
blisca
Loading thread data ...

#define TEN_FFS 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF const unsigned char my_array[8]={ 0xA, 0xB, 0xC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF TEN_FFS, TEN_FFS, TEN_FFS, TEN_FFS, TEN_FFS, TEN_FFS, TEN_FFS, TEN_FFS, TEN_FFS, TEN_FFS }; #undefine TEN_FFS

Wouter van Ooijen

Reply to
Wouter van Ooijen

I misread, you want 1000, not 100, but that requires only two more lines ;)

Reply to
Wouter van Ooijen

You could write a piece of code that pretty prints the C code you want to use to init your array?

Alternatively, there's a GNU extension in gcc to specify ranges in arrays. Something along the lines of

const unsigned char my_array[1024] = {0xA, 0xB, 0xC, [3 ... 1023] = 0xFF};

Reply to
Anssi Saari

my_array[1024] = {[0 ... 1023] = 0xFF, [0]=0x0A, [1]=0x0B, [2]=0x0C};

From the gcc docs "If the same field is initialized multiple times, it will have value from the last initialization."

search for gcc array initializer

--
Chisolm 
Republic of Texas
Reply to
Joe Chisolm

I wouldn't want to trust that for code that needs to live a long life. If your product life cycle is only a year or two, then that looks like a nifty feature to exploit.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

First, remember that what goes into memory is an image of the whole array, so you're not "wasting" any space in memory or the hex file by defining it -- at worst you're just making a .c file bigger.

Second, it's not uncommon in code that I've authored to find arrays that are generated by an application or a script into a .c file, and then compiled. This really works best if you're using a makefile: you define a .o file to be dependent on a .c (or .cpp) file, then you define that .c (or .cpp) file to be dependent on the script, then you give a rule for generating the .c file from the script. That way, you're keeping your source straight. I usually have my script generate a comment at the head of the .c file along the lines of "machine generated file, do not put under version control!!"

Third, if you're only ever going to define it once, and if you don't like Wouter's suggestion, why not just define all 1024 characters? At 8 characters per line, that's only 128 lines. That's long, but not absurdly so.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

Why would you not trust it for a long life product. Granted the OP would be better with some defines with better names. The array init feature has been in gcc for something like 10 years now. I dont think they are going to rip it out. You have to be careful about initializer values with side effects but that is not the issue here.

--
Chisolm 
Republic of Texas
Reply to
Joe Chisolm

Because even if I could trust gcc not to rip it out, I couldn't trust that, over the lifetime of the code, the need to change tools wouldn't arise.

I've been in industry for over 20 years. Using some clever non-standard compiler feature -- or even some feature that's in some clever but dusty corner of the standard -- makes you look like a hero for about a year, then makes you look like a fool.

Over time, one becomes allergic.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

I also have been in the industry for 20 years. And over the lifetime of a project, I almost never change tools. Just a few weeks ago I had to make changes to a program that I wrote 18 years ago - I compiled it with the same compiler I used 18 years ago (despite having much newer and much better tools for the same target).

So if I write code that takes advantage of a particular feature of a compiler, I know that it will still work in the future. And in practice, I seldom write code that does not involve at least some compiler-specific feature somewhere in the project (such as pragmas or function attributes for interrupt functions, etc.).

Using compiler features like this one is perfectly safe. Within the project, you will be (or should be!) using the same tools all the time - thus it still works in the same project. And if you re-use the code in a different project, then it either works fine (because you are using gcc again, or a compiler that supports the same extensions), or you get an error from your compiler. It is /highly/ unlikely that some other compiler will silently accept this syntax but interpret it in a different way.

Of course if you know (or strongly suspect) that the code you are writing has to work across a range of compilers, then you must avoid extensions. But if you are writing project-specific code, or just use the one compiler, then take advantage of any extensions that lead to cleaner and neater code - just as you use other features of your tools.

Reply to
David Brown

What you say is clearly correct, but many times tools are not "stored" with the project. I don't know about others, but for myself, it's just often too much a pain to make sure I get all the components of gcc/g++ (or whatever) into my version control. Although on my current project I have done just that.

But I agree this is the ideal, anal way to go about things.

--
Randy Yates 
Digital Signal Labs 
http://www.digitalsignallabs.com
Reply to
Randy Yates

I go along with the others who suggested that you write some C/C++ code to generate this code. I've done that many times and it works well.

--
Randy Yates 
Digital Signal Labs 
http://www.digitalsignallabs.com
Reply to
Randy Yates

If it is a one-off it is not much work to do it in an editor. The result is ugly, but could be put in a .inc file.

Wouter

Reply to
Wouter van Ooijen

Sure -- enumerate all 1024 elements! :-/

[If you *do* opt to manually specify all values, I would suggest using a form like:

const unsigned char my_array[]={ 0x0A,0x0B,0x0C,0xFF,0xFF,0xFF,0xFF,0xFF, ... };

ASSERT(sizeof(my_array[])/sizeof(my_array[0]) == 1024);

to ensure you have specified *exactly* 1024 values!]

Presumably, you are implying that you *don't* want to specify all of the elements *and* that the compiler should be able to *infer* the value you would like stored in the elements that you are *not* specifying (i.e., my_array[8] through my_array[1023] in the example above).

If those unspecified values should be '0', then you're all set (hand waving).

This then suggests reexamining your choice of 0xFF for those unspecified values and checking if 0x00 could be used just as easily (with an appropriate twist in your code). I.e., is there some *magic* about 0xFF (I can think of several examples).

You can initialize at run-time (memcpy, memset, bzero, etc) but that takes a (small) performance hit (which may change over time -- e.g., if the array's size increases).

I tend to have very large const structs in my code (I like to drive things from tables). But, *rarely* does the compiler environment (including pre-processor) lend itself to specifying those structs intuitively at compile time.

E.g., one version of the speech synthesizer I'm working with has rules like: C > ^S ] S$ < +EOUS which means: when a 'C' is detected, preceded by one of {A,E,I,O,U,Y,R,P,K,C} and followed by the suffix "EOUS", pronounce it as the "sh" sound (as in "seb a C eous")

Encoding these CONSTANTS into a form that is appropriate for the algorithm YET REMAINS "OBVIOUS" to someone perusing the code is very tedious "by hand" -- and, subject to lots of subtle errors creeping in (which can only be identified by a thorough regression test).

So, I have a piece of code that parses a text file and builds the "C source code" (just a bunch of const's) which can then be compiled. This preserves the more intuitive (ha!) form of the original rules. It also lets me embelish the "converter" with other tests and invariants that would be pretty impossible to get the compiler to check/enforce (e.g., ensuring rules exist for all possible letter combinations, or allowing me to "filter" which capabilities of the ruleset I want to retain/discard)

If you are careful with your choice of compiler features (and stdlib features used in that "converter" tool -- cuz you don't know which platform you'll be compiling this code on in the future!), you can remove any dependencies on the compiler *and* host OS that can bite you later.

[In my case, I'm reusing code I wrote over 30 years ago! And, just tweeking the representation to fit the resources that I have available in 2014 silicon. I've seen others who wrote code to a particular compiler -- e.g., MS -- that later had to do significant rewrites to "port" their code to another *host*/toolchain]

Similarly, I often build state machines in my code. I want to specify them in a grammar that makes sense for a state machine -- not some bizarre set of numerical values (that have to be derived from generic symbols HAVING NO INHERENT VALUES). The compiler is just not capable of doing this. And, the reader would be spending too much time trying to figure out the *mechanism* instead of the *algorithm* being encoded.

In *any* case, it should be clear to the reader *why* the values (especially those that are not directly specified) take on the values that they do. That it is not a case of

*you* having forgotten to initialize every value!

E.g., array[9] = {1,2,3,4,5,6,7,8};

"Hmmm... did he forget to tack ',9' on the end of that initializer list?"

Reply to
Don Y

If the binary data already exists in another file, then xxd will write out the C code for you.

Simon.

--
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP 
Microsoft: Bringing you 1980s technology to a 21st century world
Reply to
Simon Clubley

That can be debated. I once had a smallish array (I think 256 bytes) of a certain pattern to be generated. I started out by just defining it "by hand" but on testing found I kept making mistakes in the pattern. Turned out to be faster to write a program to do it.

--
Randy Yates 
Digital Signal Labs 
http://www.digitalsignallabs.com
Reply to
Randy Yates

I find it's usually _way_ faster to write a Python program to generate such things, but YMMV.

--
Grant Edwards               grant.b.edwards        Yow! How do I get HOME? 
                                  at                
                              gmail.com
Reply to
Grant Edwards

Yeah, sure, python, perl, common lisp, scheme, erlang, c, c++, etc. - pick yer' poison.

--
Randy Yates 
Digital Signal Labs 
http://www.digitalsignallabs.com
Reply to
Randy Yates

Toward the end of my corporate career I often ended up writing code that would get reused.

Using "special" features of the compiler was also discouraged because it required code reviewers to know what the compiler would actually do -- we tended to stress clarity over convenience, as long as the running code was not seriously impacted.

--

Tim Wescott 
Wescott Design Services 
http://www.wescottdesign.com
Reply to
Tim Wescott

Il 12/06/2014 22:53, Don Y ha scritto:

Lot of answers, i will read all carefully thanks again

Diego

Reply to
blisca

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.