Is enum a suitable way to implement a "local define?"


J

Jorgen Grahn

.
In general, you want to use a library, it's written in C, comes in a binary
LIB form, and might have a header containing the functions, types and data
structures used; however this is not usually designed to be human readable,
you're expected to be using a C compiler (sometimes a particular compiler,
set of options, etc).

I remember trying to read STDAFX.H, and it was totally impossible.

I can understand that, given that it's part of the worst part of
Windows. That means it's not representative.
Binary APIs are needed not APIs geared to a specific language. You
have to get involved in C source even if you have no intention of
writing any yourself.

All important libraries written in C are available in other languages,
so I don't see a desperate need for some new sort of API. There are
enough people who are able and willing to read C code.

/Jorgen
 
Ad

Advertisements

T

Tim Rentsch

Keith Thompson said:
Correction: the standard does use the term, but it doesn't define it.


I've seen that definition before. The problem with it is that it
makes a couple of statements about variables without actually saying
what a variable *is*. Perhaps the author(s) thought it was obvious.

The obvious meaning would be that the object *is* a "variable",
but it doesn't actually say so. A "variable" could also be some
abstract thingie that isn't the object, but whose name denotes the
object. It could even be a compile-time symbol table entry.

If I have an object declared in a recursive function, and there are
currently two running instances of the function, I have two object
with the same name. Is that one "variable" or two? How is either
answer supported by that definition?

The C++ standard defines the term "variable" so that there is a
single word that applies to both references and non-references.
It's there purely for convenience, and has no bearing on the
terminology issue here.

Getting back to C (which doesn't define the term), there are plenty
of contexts where the word "variable" can be used without ambiguity.
If you say that `int x = 42;` defines a variable whose name is "x",
whose type is int, and whose initial value is 42, I have no problem
with that.

The problem is when it's used where the distinction between
declarations and objects or between const and non-const objects,
or among named objects, subobjects, and allocated objects, actually
matters. In such contexts, I think it's best to stick as closely
possible to the terms defined by the standard, and to use them with
their standard-defined meanings.

Personally I don't see anything wrong with using the term
"variable". I agree it is used in several different ways, and it
does have more than one meaning depending on context. But these
ambiguities can be sorted out easily just by adding some
qualifying phrases, eg, "possibly non-modifiable variable".

Furthermore, when what we're talking about is compile time
properties, there isn't really a good alternative. The Standard
does define the term "object", but "object" is clearly wrong
here, because objects don't exist at compile time, only at
run time. This result is not some accident of wording but
spelled out quite explicitly in 6.2.4, "Storage durations of
objects". We might talk about "a declared identifier which
at runtime will designate an object" (perhaps of some particular
storage duration), but that seems rather cumbersone, does it
not? Even when people disagree on exactly what properties
a "variable" should have, I don't anyone really misunderstands
the term. If/when it's important to disambiguate the different
usages I think it's easy enough to do that.
 
T

Tim Rentsch

Keith Thompson said:
"const" in C simply means "read-only". "Constant" refers to
something that can (and must) be evaluated at compile time, as
in "integer constant" (what some languages call an "integer
literal") or a "constant expression" (an expression that can be
used as if it were a literal).

Not exactly right. An address constant is a form of constant
expression, but it can't be evaluated at compile time. It is
evaluated before program execution begins but AFAIK it is not
required to be fixed even after linking is done. That is,
different runs of the same executable might produce different
values for an "address constant". I'm pretty sure the Standard
means for an address constant to have any particular value only
within a single execution of a compiled and linked program, not
necessarily for all executions (of the same program image).
 
G

glen herrmannsfeldt

Not exactly right. An address constant is a form of constant
expression, but it can't be evaluated at compile time. It is
evaluated before program execution begins but AFAIK it is not
required to be fixed even after linking is done.

I haven't heard the term "address constant" used so much outside
of S/360 (and successor) assembler programming.
That is, different runs of the same executable might
produce different values for an "address constant".
I'm pretty sure the Standard means for an address constant
to have any particular value only within a single execution
of a compiled and linked program, not necessarily for
all executions (of the same program image).

For S/360 address constants, which may or may not generalize to
other systems, they can be either absolute or relocatable.
Absolute address constants don't change on relocation, and
relocatable ones do (maybe that is too obvious).

Pointer constant sounds more C-like to me.

The assembler stores the offset into the CSECT, the linker
updates that as it relocates it within the load module, and
program fetch updates again as it is being loaded into memory.

To get back to C, some things are required to be known at compile
time, and so compile time constants.

Among others, C doesn't require subtraction between pointers to
different objects to have a defined value. Subtracting two constant
pointers to different objects, then, should not be a compile time
constant, even though the compilers for some systems could
probably compute one. I presume C can compute a constant absolute
expression with pointers to the same object.

Another interesting feature of the OS/360 assembler that I haven't
known in others is that the relocation factor, in addition to the
usual 0 or 1, can also be -1 or 2. In C terms, you can compute
the value of -pointer, 2*pointer, or pointer1+pointer2 as an
address constant. C doesn't allow for that.

-- glen
 
J

James Kuyper

<nit-pick> Some address constants (namely, null pointers) can be
evaluated at compile time. said:
I haven't heard the term "address constant" used so much outside
of S/360 (and successor) assembler programming.

"An _address constant_ is a null pointer, a pointer to an lvalue
designating an object of static storage duration, or a pointer to a
function designator; ..." (6.6p9). The phrase "address constant" is
italicised, indicating that this sentence constitutes the definition of
that phrase.

....
For S/360 address constants, which may or may not generalize to
other systems, they can be either absolute or relocatable.

In C, address constants are not required to be absolute, nor are they
required to be relocatable - that's an implementation detail outside the
scope of the C standard.
Absolute address constants don't change on relocation, and
relocatable ones do (maybe that is too obvious).

I think it is - but "obvious" depends upon the reader.
Pointer constant sounds more C-like to me.

The C standard says otherwise.
 
T

Tim Rentsch

James Kuyper said:
<nit-pick> Some address constants (namely, null pointers) can be
evaluated at compile time.</nit-pick>

Right! I should have double checked before posting.

<counter-nit-pick>In most (okay, probably all) implmentations,
null pointer constants can be evaluated at compile time, but
I believe the Standard does not /require/ them to be evaluable
at compile time.</counter-nit-pick>
 
Ad

Advertisements

D

David Thompson

On Thu, 10 Apr 2014 19:36:53 +0000 (UTC), glen herrmannsfeldt

In computers, a more important distinction is whether memory
is allocated to store it in. A Fortran PARAMETER is normally not
considered a variable, and normally not in allocated memory.

In Java, static final variables can't be changed, but one could go
edit the file where the value was defined and put in a different one.
When declared in the same class, the compiler can optimize them just
like constants, and process constant expressions accordingly.
From a different class, I think the compiler can't do that.
If primitive type or String and initialized by a constant expression,
the compiler can AND MUST fold it. See definition of 'constant
variable' (!) in 4.12.4, and 13.1p3 and 13.4.9, in Java 7 Language
Specification; I ass-u-me 8 is the same but haven't looked yet.

In particular 13.4.9 says this should be used for "only values which
truly are unlikely ever to change" and 13.4.10 shows a kludgy way to
make the initialization of an actual constant value a non-constant
expression and thus the variable not foldable.

This is similar to C++'s making a namespace-scope const integer object
initialized by constant expression into a constant itself. C++ doesn't
require this for floating-point on the theory that runtime (target)
floating-point may differ from the compiler. Java tried to require
IEEE floating-point everywhere but had to back off.

In order to resolve overloads and check types the java compiler
already requires that all classes and interfaces referenced from and
not defined in the set of source files processed in one compilation --
what I might loosely call 'net imports' -- must be available already
compiled in CLASSPATH, usually though not necessarily in library jars.
This means the needed 'static final' values are available.
 

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

Top