simple question about inter modular acces

B

Ben Bacarisse

We are not really disagreeing about much, but there are a few things I
take issue with...

David Brown said:
Using a language to its full potential does not mean using every feature
of the language, or every possible technique. Look at Rosario1903's
code in this group - he uses the C pre-processor "to its full
potential", and is universally condemned for it.

You are of course correct that you need to take advantage of the
language and toolchain's features when the make the program better - but
the more advanced, complicated, surprising, risky or specialised the
feature or technique is, the more justification you need to use it.

I don't think these are all same at all. You probably need a huge
justification to use a risky feature, and very little to use one that is
specialised. Some of the others may not need any justification at all.
If I use a surprising feature, I'll just write a comment about it
(provided I can guess that it will be considered surprising). I won't
necessarily think it needs any justification to use it since the comment
immediately renders it unsurprising.

Now, you may well think that I'm just picking nits -- that all this is
properly wrapped up in the basic, un-contentious idea, that everything
in a program needs to have suitable justification for it's use -- that
all I'm doing is quibbling about the details -- but I think there really
is a different view of programming here.

From the way you've expressed it, I suspect that the meaning of
"justification" is not far off from "having a good reason to do
something bad" (this may be a misreading on my part) but I see it very
differently. A program with an explained, but surprising, bit of code
is better than one without. The surprise is the justification.
Note also there is a big difference between what you do "to learn stuff"
and what you do when writing serious code that must work, and be
supported and maintainable for years to come.

Just to be clear, when I talked about learning stuff I was not talking
about writing code to learn stuff. I was talking about the joy of
learning something in the middle of a tedious bit of program porting or
maintenance.
When trying things out
and learning new stuff, or writing code for fun, it's fine to push
yourself and your tools to the limits. But when you are working
professionally, you take a step back to avoid the risk of going over
these limits.

This takes a narrow view of professional programming. I wrote code for
some years at a leading research university. I would have lost this
professional job if I had not pushed myself and been continually learning
new stuff. Working right up to the limits of the tools was required.

Just another nit-pick? Maybe. But professional programmers do all
kinds of things, and the degree to which they must suppress their joy
and exuberance about the task varies greatly. Writing code to control a
pacemaker is very different to writing code to crack a code.

Because of the overlap between C and C++, and between C programmers and
c++ programmer (and perhaps more importantly, the /imagined/ overlap in
the languages as many programmers think of C++ as a pure superset of C),
it /does/ matter if you use a technique in C that cannot be used in C++.
Sometimes a C-only feature is useful enough that it is worth using -
but you should view "incompatibility with C++" as a disadvantage of such
features, which will weigh against its use.

I think there are piles and piles of C code that will never go near a
C++ compiler. I would weigh as close zero as possible the disadvantage
of using 'mutable' as a variable name in some C libraries. Let's not
forget that there is also harm in terms time and effort when a C
programmer is always looking over their shoulder at C++.

<snip yet more points of agreement>
 
J

James Kuyper

On 09/27/2013 07:55 AM, David Brown wrote:
....
You are of course correct that you need to take advantage of the
language and toolchain's features when the make the program better - but
the more advanced, complicated, surprising, risky or specialised the
feature or technique is, the more justification you need to use it.

I can agree with that - but since recursive calls to main() are no more
advanced, complicated, risky or specialized than any other kind of
recursive function calls, it follows that they don't require much
justification.

I think it's relatively rare that recursive calls to main() are
justified, but that's not because a lot of justification is required,
it's just because it's unusual for recursion of main() to be a
reasonable thing to want to do. The interface of a recursive function
generally needs to be designed with the intended recursion in mind, and
main() was not so designed.
 
S

Seebs

I don't think that it's legitimately a readability or maintainability
issue. Code that directly or indirectly calls main() is not
intrinsically any less readable or maintainable than any other recursive
code. If you allow recursion at all (and I have heard arguments against
allowing recursion), there's no reason for excluding main() from the
list of functions that can be called recursively.

I would disagree with this. Most of the functions in your code, you are
the caller, or you at least invoke the caller. By contrast, main() is
invoked at least once by not-your-code, and that creates a significant
distinction. Furthermore, there is a lot of code which does special
one-time-only setup early in main(), enough so that if you haven't
studied the entire code base of a large program, it's pretty reasonable
to assume that it is safe to add a one-time initialization statement
to main(), because main() is only invoked once.

So I'd expect a great deal of warning if main() were to be invoked, whether
directly or indirectly, by anything within the code. And I would, in
general, just plain not do it -- it is too likely to confuse someone else
maintaining the code later. Even if someone is me.

-s
 
T

Tim Rentsch

Keith Thompson said:
Tim Rentsch said:
It is not uncommon in embedded systems for main to be treated
specially. Some compilers inject extra code at the beginning of
main() as an alternative to doing it in the startup code (typical
"run before main" code includes basic hardware initialisation,
memory setup, stack setup, clearing bss, copying .data from flash,
etc.). [snip]

Any C implementation that puts extra code at the beginning of
main is non-conforming, no matter hosted or freestanding. Any
such code must run before calling the designated entry function
(whether that function is main or some other function).

How is it non-conforming?

If your concern is the possibility of the code being executed
again if main is called recursively, the injected code could be
something like:

static int __initialized = 0;
if (!__initialized) {
/* startup code */
__initialized = 1;
}

Or the check could be optimized out if the compiler/linker detects
that main isn't called recursively.

You are implicitly invoking the as-if rule, and I agree that
applies here. As long as main() acts /as if/ it has no extra
code before its body as defined by the source program, then
it doesn't matter whether the actual machine language has
additional instructions or not.

However, if main() acts as if it has /any other code/ (in the
sense of observable behavior) beside that given in its function
definition in the program source, then the implementation that
produced such a result is necessarily non-conforming.
 
T

Tim Rentsch

David Brown said:
David Brown said:
On 23/09/13 19:45, Keith Thompson wrote:
[...]
I believe you actually can call main from your hosted program in C
(not in C++), although I can't imagine a case where that would
actually be a good idea. And in a freestanding program, main isn't
special at all.

In a freestanding program, main *may or may not* be special. The
program entry point is implementation-defined; it may well be called
"main".

N1570 5.1.2.1:

In a freestanding environment (in which C program execution
may take place without any benefit of an operating system),
the name and type of the function called at program startup are
implementation-defined. Any library facilities available to a
freestanding program, other than the minimal set required by
clause 4, are implementation-defined.

The effect of program termination in a freestanding environment
is implementation-defined.



It is not uncommon in embedded systems for main to be treated
specially. Some compilers inject extra code at the beginning of
main() as an alternative to doing it in the startup code (typical
"run before main" code includes basic hardware initialisation,
memory setup, stack setup, clearing bss, copying .data from flash,
etc.). [snip]

Any C implementation that puts extra code at the beginning of
main is non-conforming, no matter hosted or freestanding. Any
such code must run before calling the designated entry function
(whether that function is main or some other function).

Few, if any, embedded C compilers conform /fully/ to any C
standard. [snip elaboration]

The problem with this line of reasoning is you are using the
behavior of these implementations to justify your attitude, but
it is precisely because of the attitude of people like yourself
that such non-conforming behaviors persist. What it boils down
to is a willingness to accept sloppy work - there is no intrinsic
reason why these implementations should ever be deliberately
non-conforming.
 
T

Tim Rentsch

James Kuyper said:
The interface of a recursive function generally needs to be
designed with the intended recursion in mind, and main() was not
so designed.

Bad reasoning. Any function interface, in the sense of any
function prototype declaration (in C), is suitable for recursion.
Whether a particular function is suitable for recursion depends not
on the function's interface (ie prototype) but on its semantics.
The specification for main() gives only its interface, not its
semantics. There is nothing inherent in main()'s interface
that argues against calling main() recursively.

It may be that the expected use-case for main() argues against
calling it recursively, but again this is not inherent in main()'s
interface - it derives solely from what people expect, not how
main() is specified.
 
M

Malcolm McLean

I am sceptical to the idea that there can be code that is best
structured as this:


void foo(int argc, char **argv) {

...

main(argc, argv);
...

}



int main(int argc, char **argv) {

...

foo(argc, argv);

...

}

Consider this


void *safemalloc(int N)
{
void *answer = malloc(N);
if(!answer)
reboot();
return answer;
}

void reboot()
{
register int (*fptr)(int argc, char **argv) = main;

zerooutbss();
vandaliseandtrashstack();
/* now we don't have a stack any more */
(*fptr)(0, 0);
}
 
G

glen herrmannsfeldt

Tim Rentsch said:
(snip)
Few, if any, embedded C compilers conform /fully/ to any C
standard. [snip elaboration]
The problem with this line of reasoning is you are using the
behavior of these implementations to justify your attitude, but
it is precisely because of the attitude of people like yourself
that such non-conforming behaviors persist. What it boils down
to is a willingness to accept sloppy work - there is no intrinsic
reason why these implementations should ever be deliberately
non-conforming.

I am not so sure. Much of embedded, and I mean mostly the smaller
sytems about the size of the 8049 or 8051, are fairly specialized
(reading and writing to I/O ports) and not ported so often.

Not that they never need to be ported, but less often than for
larger systems.

Also, they often need to fit into a specific (and small) memory size,
and anything that helps them fit helps overall.

-- glen
 
K

Keith Thompson

Tim Rentsch said:
Few, if any, embedded C compilers conform /fully/ to any C
standard. [snip elaboration]

The problem with this line of reasoning is you are using the
behavior of these implementations to justify your attitude, but
it is precisely because of the attitude of people like yourself
that such non-conforming behaviors persist. What it boils down
to is a willingness to accept sloppy work - there is no intrinsic
reason why these implementations should ever be deliberately
non-conforming.

With emphasis, I suggest, on *deliberately*.

I've read documentation for an embedded C compiler that provides
types `long` and `long long`, and makes them both 32 bits (without
acknowledging that this violates the requirement that `long long`
must be at least 64 bits wide). That, IMHO, is just sloppy.

On the other hand, a small target system might not have reasonable
support for 64-bit integers, or for floating-point. In that case, I
think it can be reasonable not to provide support for those features,
to have a compiler for a language that's very similar to C but that
fails to meet a well-defined subset of its requirements. Sure, you
could support such features in software, but that might not be worth
the effort, and there might not be any user demand for such features.

My own preference would be to implement as much of the standard as
is *reasonable*, and to document the non-conformities as clearly as
possible, with the goal of surprising any experienced C programmer
as rarely as possible. If I write C code and it fails to compile
because a feature isn't supported, that's ok. If I write C code
and it behaves in an unexpected manner, that's less ok.
 
G

glen herrmannsfeldt

(snip)
Agreed.
(snip)

The only thing that annoys me is hidden non-conformities that break
major parts of the standards. A key example is one major toolchain
from a major microcontroller/DSP manufacturer that does not zero
uninitialised data. If you write "int foo;", then "foo" will not be
zeroed at pre-main startup. This is "documented" as a footnote in
the middle of the 400+ page manual!

It may not be the same one, but one that I know doesn't initialize
otherwise uninitialized static data that is stored in flash. That
allows one to keep values from one execution to the next.

Unlike the usual case where a program is loaded into memory when
you ask to run it, in the case of flash it is loaded once and stays
there forever. (Until you specifically remove it.)

Seems like a case that the original C standard didn't consider.

-- glen
 
M

Malcolm McLean

On 23/10/13 09:25, glen herrmannsfeldt wrote:

Do you mean eeprom here, rather than flash? (Or at least, eeprom
simulated using flash.) Flash does not allow direct write access -
unintialised data in flash does not make much sense. Usually, data that
is placed in flash sections are "const" and never changed.
You can write a zero, but not a one.
So you can work out all sorts of complex interactions when you try to
overwrite ascii messages with each other.
 
T

Tim Rentsch

Keith Thompson said:
Tim Rentsch said:
Few, if any, embedded C compilers conform /fully/ to any C
standard. [snip elaboration]

The problem with this line of reasoning is you are using the
behavior of these implementations to justify your attitude, but
it is precisely because of the attitude of people like yourself
that such non-conforming behaviors persist. What it boils down
to is a willingness to accept sloppy work - there is no intrinsic
reason why these implementations should ever be deliberately
non-conforming.

With emphasis, I suggest, on *deliberately*.
Absolutely.

I've read documentation for an embedded C compiler that provides
types `long` and `long long`, and makes them both 32 bits (without
acknowledging that this violates the requirement that `long long`
must be at least 64 bits wide). That, IMHO, is just sloppy.

Mine too.
On the other hand, a small target system might not have
reasonable support for 64-bit integers, or for floating-point.
[snip elaboration]

Yes but it doesn't have to. The bar for a freestanding
implementation is very low, because there is no lower bound on
the maximum object size that must be supported. A freestanding
implementation could simply not accept any program that uses
any type larger than 16 bits, with a diagnostic indicating an
environmental limit has been exceeded. Support for underranged
types, or unusual floating-point environments, could be enabled
by using #pragma or defining a symbol like __BOGUS. The result
satisfies both criteria - it can support very small systems,
and would also be a conforming implementation.
 
T

Tim Rentsch

glen herrmannsfeldt said:
Tim Rentsch said:
David Brown said:
Few, if any, embedded C compilers conform /fully/ to any C
standard. [snip elaboration]

The problem with this line of reasoning is you are using the
behavior of these implementations to justify your attitude, but
it is precisely because of the attitude of people like yourself
that such non-conforming behaviors persist. What it boils down
to is a willingness to accept sloppy work - there is no intrinsic
reason why these implementations should ever be deliberately
non-conforming.

I am not so sure. Much of embedded, and I mean mostly the smaller
sytems about the size of the 8049 or 8051, are fairly specialized
(reading and writing to I/O ports) and not ported so often.

Not that they never need to be ported, but less often than for
larger systems.

Also, they often need to fit into a specific (and small) memory size,
and anything that helps them fit helps overall.

Please see my response to Keith Thompson's post in this
subthread.
 
T

Tim Rentsch

David Brown said:
David Brown said:
On 25/09/13 06:56, Tim Rentsch wrote:

On 23/09/13 19:45, Keith Thompson wrote:
[...]
I believe you actually can call main from your hosted program in C
(not in C++), although I can't imagine a case where that would
actually be a good idea. And in a freestanding program, main isn't
special at all.

In a freestanding program, main *may or may not* be special. The
program entry point is implementation-defined; it may well be called
"main".

N1570 5.1.2.1:

In a freestanding environment (in which C program execution
may take place without any benefit of an operating system),
the name and type of the function called at program startup are
implementation-defined. Any library facilities available to a
freestanding program, other than the minimal set required by
clause 4, are implementation-defined.

The effect of program termination in a freestanding environment
is implementation-defined.



It is not uncommon in embedded systems for main to be treated
specially. Some compilers inject extra code at the beginning of
main() as an alternative to doing it in the startup code (typical
"run before main" code includes basic hardware initialisation,
memory setup, stack setup, clearing bss, copying .data from flash,
etc.). [snip]

Any C implementation that puts extra code at the beginning of
main is non-conforming, no matter hosted or freestanding. Any
such code must run before calling the designated entry function
(whether that function is main or some other function).


Few, if any, embedded C compilers conform /fully/ to any C
standard. [snip elaboration]

The problem with this line of reasoning is you are using the
behavior of these implementations to justify your attitude, but
it is precisely because of the attitude of people like yourself
that such non-conforming behaviors persist. What it boils down
to is a willingness to accept sloppy work - there is no intrinsic
reason why these implementations should ever be deliberately
non-conforming.

This is digging up an old thread...

There are very good reasons why many embedded C compilers are not
fully conforming, especially to later standards. In particular,
there are many parts of the library that are irrelevant to small
systems, and would lead to bigger and slower code.

That doesn't apply to freestanding implementations - their
library requirements can be provided with essentially zero
execution-time footprint.
There are also
embedded architectures for which standard C compiler features are
very difficult to implement well. For targets like the 8051, it
is common to make functions non-reentrant, because implementing a
data stack is so inefficient.

Strictly speaking that doesn't make such implementations
non-conforming, because there are no requirements on what depth
of function calls must be supported (and exceeding that depth is
undefined behavior). Personally I would rather have such
behavior require an explicit enabling, eg #pragma or a compiler
option, but technically that is a QOI concern, not a conformance
concern.
Proper 64-bit doubles would be absurd on such a processor.

As I explained in my response to Keith Thompson's post, they
don't have to.
And so on...

Please go on and list any other factors you think relevant. None
of the factors listed thus far presents any significant barrier
to providing conformance.
There are also arguably less good reasons, such as missing out
features that /would/ be possible to implement, but will almost
certainly never be used (say, wide character support on an 8-bit
microcontroller).

Again, as with floating-point support, they don't have to.
Should the toolchain developers increase their
costs just because a standards committee thought the feature
would be useful on totally different kinds of system?

You seem to think the WG14 committee doesn't differentiate
between different kinds or sizes of systems. They do, and that
is reflected explicitly in the ISO Standard. Furthmore the
committee meetings are open to outsiders, and IME they are
interested to receive additional input. If the interests of
toolchain developers aren't being represented that's as much
their fault as anyone else's.

Even ignoring that though, I still would say Yes, because the
costs are actually not very high, and affect a comparatively
small number of people, and the benefits are substantial,
especially when multiplied by the much larger number of people
who use the toolchains.
Still, in general I like to see toolchains get as close as they
can to the standards.

I think if you had a better understanding of what the Standard
actually requires for an implementation to be conforming, you
would come around to the point of view that toolchains should be
(at least) completely conforming, full stop.
 
G

glen herrmannsfeldt

Tim Rentsch said:
That doesn't apply to freestanding implementations - their
library requirements can be provided with essentially zero
execution-time footprint.

To be sure we know about what is being discussed, the 8051,
a typical embedded processor, has 128 bytes RAM and 4K ROM.
The stack and data go into that 128 bytes.

There is a possibility to add external RAM or ROM.
Strictly speaking that doesn't make such implementations
non-conforming, because there are no requirements on what depth
of function calls must be supported (and exceeding that depth is
undefined behavior). Personally I would rather have such
behavior require an explicit enabling, eg #pragma or a compiler
option, but technically that is a QOI concern, not a conformance
concern.

-- glen
 
K

Keith Thompson

Tim Rentsch said:
On the other hand, a small target system might not have
reasonable support for 64-bit integers, or for floating-point.
[snip elaboration]

Yes but it doesn't have to. The bar for a freestanding
implementation is very low, because there is no lower bound on
the maximum object size that must be supported. A freestanding
implementation could simply not accept any program that uses
any type larger than 16 bits, with a diagnostic indicating an
environmental limit has been exceeded. Support for underranged
types, or unusual floating-point environments, could be enabled
by using #pragma or defining a symbol like __BOGUS. The result
satisfies both criteria - it can support very small systems,
and would also be a conforming implementation.

Hmm.

I can imagine a very small system (8051 may qualify, but I'm not
sufficiently familiar with it to be sure) for which floating-point
support just doesn't make sense.

Practically speaking, I'd rather see a statement like:

This is a nearly conforming C11 freestanding implementation, with
the exceptions that integers wider than 16 bits and floating-point
types of any size are not supported.

than:

This is a fully conforming C11 freestanding implementation. (Oh,
and you're not going to be able to use floating-point because scalar
types wider than 16 bits run into an environmental limit documented
in section X.Y paragraph Z.)

(Perhaps support for floating-point and for wide integer types
should be optional for freestanding implementations, but as of
C11 I personally think the standard has too many optional features
already.)

I see little point in doing arbitrary things *that are not useful
to users* to be able to claim full C conformance.

(This applies only to small resource-limited freestanding
implementations. The underlying systems for hosted implementations
are powerful enough to support full conformance. Yes, I'm talking
to you, Microsoft!)
 
J

James Kuyper

To be sure we know about what is being discussed, the 8051,
a typical embedded processor, has 128 bytes RAM and 4K ROM.
The stack and data go into that 128 bytes.

There is a possibility to add external RAM or ROM.

"A conforming freestanding implementation shall accept any strictly
conforming program in which the ∗ use of the features specified in the
library clause (clause 7) is confined to the contents of the standard
headers <float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>,
<stdbool.h>, <stddef.h>, <stdint.h>, and <stdnoreturn.h>." (4p6)

The specified headers do not declare even a single function, nor a
single object. They only define macros and types. Many of those macros
have precisely specified expansions. Many of the others are required to
expand to constants suitable for use in #if conditions, and many of the
rest are required to expand into constants or constant expressions. The
only obstacles to having a standard library that occupies exactly 0
bytes at execution-time are the function-like macros from <stdarg.h>.

I have no idea whether it's even possible to implement <stdarg.h> on a
typical embedded processor. On any system where it is not possible, no
implementation of C can conform fully to even the relaxed requirements
for a freestanding implementation. However, if <stdarg.h> can be
implemented, the expansion of those macros might have to include calls
to one or more library functions. Within memory limits as tight as the
ones you specify, those functions might require a prohibitive amount of
space.
 
K

Keith Thompson

David Brown said:
One clear example is that on at least one compiler I have used, "const"
is used to mean "put the data in flash" on a microcontroller that uses
different instruction codes for accessing data in flash from accessing
data in ram. This is quite convenient for many programs on these
devices, and is easy to understand (arguably easier than the gcc port
for that device, which requires macros and attributes to access data in
flash correctly in a standards-compliant manner). But it also means
that you can't cast a "int *" into a "const int *" and expect it to work
- breaking standards and breaking a lot of code.

If it really is as you describe, then I'd say that's a bad way to do it.
Do you have a reference for that?

The "const" keyword has a clear meaning in C, such that

const int r = rand();

is perfectly valid and meaningful. (Replace rand() by some other
function call if <stdlib.h> isn't supported.)

Compilers for small embedded systems have special needs, but
they can meet those needs without mangling existing semantics.
For example, if you need to be able to specify that some data
should be stored in flash, adding a new keyword like "__flash"
would be a perfectly reasonable way to do it -- which would let
"const" continue to be used for its intended purpose.

[...]
 
J

James Kuyper

On 24/10/13 17:26, Tim Rentsch wrote: ....
If freestanding compilers are freed from obligations regarding the
library when considering standards compliance, then embedded compilers
are a lot closer to standards-compliant than I previously thought. And
many will be fully C90 compliant at least.

They're freed from obligations regarding almost all of the standard
library, but not quite all of it. I've quoted the clause (4p6) that
specifies precisely how their obligations are reduced, in another branch
of this thread.

....
I am almost certain that this is not correct - but I don't know the
details of the standards well enough.

The standard requires that any implementation be able to translate and
correctly execute one program that, among many other requirements, must
pass at least 127 arguments in one function call (5.2.4.1p1). It does
not require that a conforming implementation be able to translate and
correctly execute ANY other program, containing any larger (or for that
matter, smaller) number of function calls, whether or not those calls
are recursive. Note also that the "one program" could meet all of the
requirements imposed upon it, while being functionally equivalent to
"int main() {}". The single most important fact, of course, is that the
"one program" is extremely unlikely to be the same as your program.
Compilers for targets where re-entrance would be very expensive (due to
poor addressing modes) usually default to non-entrant code, and let you
use pragmas (or extra keywords) when you really need the re-entrancy. I
believe this behaviour is non-conformant, but maybe I'm wrong.

Because of 5.2.4.1p1, I don't think they need be non-conformant.
Again, if it is true that a freestanding compiler has such low
requirements for conformance, then most of what I thought was
non-conformance is incorrect.

A conforming implementation of C is required to provide not only double,
but also long double. The minimum requirements it imposes on a 'long
double' are the same as those it imposes on 'double'. They do not
require 64 bits. They can be met by a type with as few as 41 bits, if
I've done my calculations correctly.

The standard imposes no requirements on the accuracy of any floating
point operations, other than that the accuracy be documented - and the
documentation is explicitly allowed to state that "the accuracy is
unknown" (5.2.4.2.2p6). It does impose some fairly strict requirements
on the conversion of floating point constants to floating point values
(6.4.4.2p3). However, about the only thing that can be done with those
values to prove whether those requirements have been met is to compare
them for relative order with each other - those comparisons are not
covered by 5.2.4.2.2p6 (some hexadecimal floating point constants can
also usefully be compared for equality, if FLT_RADIX is a power of 2).
However, if you are correct here, then "standards" become almost useless
in the embedded world because compiler implementers have too much freedom.

A strict interpretation of 5.2.4.1p1 renders the C standard almost
completely useless. Most people (myself included) prefer to think in
terms of a modified version of the standard in which 5.2.4.1p1 means
something different and more useful - unfortunately, there's no
agreement, and therefore, no precise specification, of what that
"something different" is, or should be.
 
A

Albert van der Horst

Do you mean eeprom here, rather than flash? (Or at least, eeprom
simulated using flash.) Flash does not allow direct write access -
unintialised data in flash does not make much sense. Usually, data that
is placed in flash sections are "const" and never changed.

In an embedded system, it may make perfect sense to write to flash
and of course there is library code to do it.
Flash sections can be erased and rewritten.

I'm a close follower of some Forth compilers for the MPS430 and
writing to flash is a large part of what makes those compilers useful.

Where with small systems you have to make most of it, I don't think
even for c-compilers that what you say is true.
What about a system that is coupled to an internet device, and upon
a cold start find the mac address and stores it? Then the next time
it finds the mac address ready to use.
Groetjes Albert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top