contiguous in memory

H

Hicham Mouline

void f()
{
auto v1;
auto v2; // consecutive in source code
....
}

Are there any guarantees by c++ that the 2 auto variables are such that &v2
== &v1 + sizeof(v1) ? are they contiguous?

if not, my question becomes empirical here
1. under x86-64, is this always true?
2. under x86-64 msvc, is this always true?
3. under x86-64 g++4.x is this always true?

regards,
 
V

Victor Bazarov

Hicham said:
void f()
{
auto v1;
auto v2; // consecutive in source code

"auto" what? You don't have a type specified, and no initialisation to
derive the type from.
....
}

Are there any guarantees by c++ that the 2 auto variables are such that &v2
== &v1 + sizeof(v1) ? are they contiguous?

No, of course not. Not to mention that the optimizer can omit placing
them in memory altogether.
if not, my question becomes empirical here

A question cannot be empirical. An answer can be.
1. under x86-64, is this always true?

Not likely. Why would it differ from the general answer?
2. under x86-64 msvc, is this always true?

Ask in the msvc newsgroup.
3. under x86-64 g++4.x is this always true?

Ask in the gnu newsgroup.

V
 
P

Pascal J. Bourguignon

Hicham Mouline said:
void f()
{
auto v1;
auto v2; // consecutive in source code
....
}

Are there any guarantees by c++ that the 2 auto variables are such that &v2
== &v1 + sizeof(v1) ? are they contiguous?

if not, my question becomes empirical here
1. under x86-64, is this always true?

Depends on the compiler.
2. under x86-64 msvc, is this always true?

What is documented?

3. under x86-64 g++4.x is this always true?

What is documented?

AFAIK, nothing is documented and there may be optimization levels such
as whatever may happen. In particular, with some optimization levels,
if you don't take the address of a variable, or even if you take its
address at a different time, it may be stocked in a register, or not
exist at all in the generated code.

If you want to have some relationship between the two variables, you could do:

auto int variables[2];
#define v1 variables[0]
#define v2 variables[1]

and then, &(v1) - &(v2) == 1
 
V

Victor Bazarov

Pascal said:
[..]
If you want to have some relationship between the two variables, you could do:

auto int variables[2];
#define v1 variables[0]
#define v2 variables[1]

and then, &(v1) - &(v2) == 1

I'd probably go with

int variables[2], &v1 = variables[0], &v2 = variables[1];

Macros give me the creeps.

V
 
A

Alan Woodland

Pascal said:
Hicham Mouline said:
void f()
{
auto v1;
auto v2; // consecutive in source code
....
}

Are there any guarantees by c++ that the 2 auto variables are such that &v2
== &v1 + sizeof(v1) ? are they contiguous?

No, there's no guarantee. In particular you may have &v1 < &v2 or &v1 > &v2 . [snip]
If you want to have some relationship between the two variables, you could do:

auto int variables[2];
#define v1 variables[0]
#define v2 variables[1]

and then, &(v1) - &(v2) == 1
Why the macro and not references? It would lead to much more natural
'scoping' in this case.

Alan
 
P

Phlip

auto int variables[2];
#define v1 variables[0]
#define v2 variables[1]

and then, &(v1) - &(v2) == 1
Why the macro and not references? It would lead to much more natural
'scoping' in this case.

More to the point, I thought 'auto' was abandoned / ignored / deprecated or
something - same as 'register' and 'entry', right?
 
J

James Kanze

Victor said:
Pascal said:
[..]
If you want to have some relationship between the two variables, you
could do:
auto int variables[2];
#define v1 variables[0]
#define v2 variables[1]
and then, &(v1) - &(v2) == 1
I'd probably go with
int variables[2], &v1 = variables[0], &v2 = variables[1];
Especially if there's an unrelated v1 or v2 in some later scope.

You can always #undef them at the end of the function.

Like Victor, macros bother me at some very fundamental level,
and given that there's a good solution which doesn't use macros,
I'd use it. But the solution with macros does work, provided
you don't forget the #undef.
 
J

James Kanze

Phlip said:
auto int variables[2];
#define v1 variables[0]
#define v2 variables[1]
and then, &(v1) - &(v2) == 1
Why the macro and not references? It would lead to much
more natural 'scoping' in this case.
More to the point, I thought 'auto' was abandoned / ignored
/ deprecated or something - same as 'register' and 'entry',
right?
'entry'? What's 'entry'?

A reserved word in K&R C, for some yet unimplemented
functionality. Probably planned to be the same thing as entry
in Fortran---an alternative entry point into a function.
 
R

Richard Herring

Victor Bazarov said:
Phlip said:
auto int variables[2];
#define v1 variables[0]
#define v2 variables[1]

and then, &(v1) - &(v2) == 1
Why the macro and not references? It would lead to much more natural
'scoping' in this case.
More to the point, I thought 'auto' was abandoned / ignored /
deprecated or something - same as 'register' and 'entry', right?

'entry'? What's 'entry'?

Fortran, sorry, FORTRAN, IIRC.
 
J

James Kanze

James said:
Victor Bazarov wrote:
Pascal J. Bourguignon wrote:
[..]
If you want to have some relationship between the two
variables, you could do:
auto int variables[2];
#define v1 variables[0]
#define v2 variables[1]
and then, &(v1) - &(v2) == 1
I'd probably go with
int variables[2], &v1 = variables[0], &v2 = variables[1];
Especially if there's an unrelated v1 or v2 in some later
scope.
You can always #undef them at the end of the function.
You can work around almost anything. That doesn't make it a
good idea.

Whether this is a "work-around" or simple "correct use of the
tool" depends. In this particular case, I'd not use a macro,
because C++ has a better mechanism. In some other cases,
however, I've found macros with limited scope to be useful. C++
can require a lot of boilerplating, and macros are one way of
handling it.
They bother me when they are mixed in with code proper, since
they play by a completely different set of rules.

True, but then, almost by definition, so does much that
*generates* code. Using macros for e.g. constants is a bad
idea, because C++ has support for constants (C didn't, and still
doesn't) at the language level---there's no need for code
generation. But there are cases where code generation is
relevant---in such cases, you have three choices: an external
generator, templates and macros. And which one is most
appropriate depends on the context, and what you are generating.

[example deleted...]
This seems simple in a Usenet post, but it took several
miserable hours to debug in the real world.

Macros can certainly be (and in the past, often have been)
misused. If there's another alternative which provides the same
functionality, I'll generally prefer it. But that isn't always
the case.
The preprocessor can be used for great things, but it is not a
general-purpose programming tool. In particular, it often has
nasty interactions with the language being preprocessed.

I think the problem would better be described as that it has no
interactions with the language being preprocessed. It just does
a textual substitution, with no consideration about the context
(and when things like name binding are considered, the context
affects the meaning of a sequence of tokens very much).

This is one of the reasons I said that you need an #undef. It
guarantees that the macro won't be expanded outside of the scope
where its expansion makes sense. (But there are other macros
where #undef doesn't make sense.)
 
J

James Kanze

In message <[email protected]>, Victor Bazarov
Phlip said:
auto int variables[2];
#define v1 variables[0]
#define v2 variables[1]
and then, &(v1) - &(v2) == 1
Why the macro and not references? It would lead to much more natural
'scoping' in this case.
More to the point, I thought 'auto' was abandoned / ignored /
deprecated or something - same as 'register' and 'entry', right?
'entry'? What's 'entry'?
Fortran, sorry, FORTRAN, IIRC.

It's listed as a keyword in K&R I. The only other mention of it
is immediately after the list of keywords: "The entry keyword is
not currently impolemented by any compiler but is reserved for
future use."

That future never came.
 
A

Alf P. Steinbach

* James Kanze:
In message <[email protected]>, Victor Bazarov
Phlip wrote:
auto int variables[2];
#define v1 variables[0]
#define v2 variables[1]
and then, &(v1) - &(v2) == 1
Why the macro and not references? It would lead to much more natural
'scoping' in this case.
More to the point, I thought 'auto' was abandoned / ignored /
deprecated or something - same as 'register' and 'entry', right?
'entry'? What's 'entry'?
Fortran, sorry, FORTRAN, IIRC.

It's listed as a keyword in K&R I. The only other mention of it
is immediately after the list of keywords: "The entry keyword is
not currently impolemented by any compiler but is reserved for
future use."

That future never came.

To supplement that, the 'fortran' keyword of K&R I C was spelled in *lowercase*,
that is, 'fortran', not 'Fortran' or 'FORTRAN'.


Just my 3c,

- Alf
 
J

James Kanze

* James Kanze:

[...]
To supplement that, the 'fortran' keyword of K&R I C was
spelled in *lowercase*, that is, 'fortran', not 'Fortran' or
'FORTRAN'.

In my copy of "The C Programming Language" (1st edition),
"fortran" isn't in the list of keywords. It does say, however,
that "Some implementations also reserver the words `fortran' and
`asm'."
 
A

Alf P. Steinbach

* James Kanze:
* James Kanze:
In message <[email protected]>, Victor Bazarov
<[email protected]> writes
[...]
More to the point, I thought 'auto' was abandoned /
ignored / deprecated or something - same as 'register'
and 'entry', right?
'entry'? What's 'entry'?
Fortran, sorry, FORTRAN, IIRC.
It's listed as a keyword in K&R I. The only other mention
of it is immediately after the list of keywords: "The entry
keyword is not currently impolemented by any compiler but is
reserved for future use."
That future never came.
To supplement that, the 'fortran' keyword of K&R I C was
spelled in *lowercase*, that is, 'fortran', not 'Fortran' or
'FORTRAN'.

In my copy of "The C Programming Language" (1st edition),
"fortran" isn't in the list of keywords. It does say, however,
that "Some implementations also reserver the words `fortran' and
`asm'."

Is your point that 'fortran' wasn't a keyword, just a word that C compilers
reserved?

Hello?


Cheers,

- Alf
 
H

Hicham Mouline

Hicham Mouline said:
void f()
{
auto v1;
auto v2; // consecutive in source code
....
}

Are there any guarantees by c++ that the 2 auto variables are such that
&v2 == &v1 + sizeof(v1) ? are they contiguous?

if not, my question becomes empirical here
1. under x86-64, is this always true?
2. under x86-64 msvc, is this always true?
3. under x86-64 g++4.x is this always true?

regards,
Thanks for the various answers provided.
The post has totally diverged :)
I didn't use "auto" as the actual keyword, but barely meant an automatic
variable...

anyways, I simplified my actual question to keep the bare minimum but this
was wrong.

I am looking at 2-dimensional double arrays, and the problem at hand is to
solve a small system of linear equations
that can be written in matrix form A.x = b where A is the 2-dim array....

There are many available implementations of multidim arrays, 2 of which are
.. boost::multi_array<type, dim>
.. boost::numeric::ublas::matrix templates

and I was just curious about performance, and using c++ native arrays, such
that I can
pass around something which I can index as a[j] where i is the row
index and j is the col index,
and i would then compare at least these 3 ( native array, boost::multi_array
and boost::.....::matrix )
ignoring for now L1/L2 cache issues and the layouts
0<=i<I 0<=j<J

* using native arrays
1 way I could do is with dynamic allocation
double** a = new double*;
a[0] = new double[J];
....
a[I-1] = new double[J];
and then pass around a which is a double**
and then delete appropriately.


Another way, preferably, on the stack, as it should be faster, with
"in-place" new operators...
Is this possible?


A third way, a hack, in case the sizes I and J are known at compile time,
double* Aptr;
double A[I*J];
Aptr=A+i*J; // for all 0<=i<I
then reinterpret_cast of Aptr to be an double**
and so calling a function would look like f(
reinterpret_cast<double**>(Aptr) , I, J );
and f may then be defined as
f(double** A, size_t I, size_t J)
{
A[j] // would have its intended meaning
}

I though mistakenly that the above would require Aptr and A to be contiguous
on the stack, but it doesn't,
it still works even if they are not.
Ignoring this point, is the above snippet valid c++?

regards,
 

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

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,044
Latest member
RonaldNen

Latest Threads

Top