Skip to content

Commit 9f5bfb1

Browse files
author
ripley
committed
improvements to handling and docs of dim<-
git-svn-id: https://svn.r-project.org/R/trunk@90454 00db46b3-68df-0310-9c12-caf00c1e9a41
1 parent 3c62619 commit 9f5bfb1

3 files changed

Lines changed: 18 additions & 12 deletions

File tree

src/library/base/man/dim.Rd

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
% File src/library/base/man/dim.Rd
22
% Part of the R package, https://www.R-project.org
3-
% Copyright 1995-2010 R Core Team
3+
% Copyright 1995-2026 R Core Team
44
% Distributed under GPL 2 or later
55

66
\name{dim}
@@ -18,7 +18,8 @@ dim(x) <- value
1818
\arguments{
1919
\item{x}{an \R object, for example a matrix, array or data frame.}
2020
\item{value}{for the default method, either \code{NULL} or
21-
a numeric vector, which is coerced to integer (by truncation).}
21+
a numeric vector, which is coerced to integer (by truncation). After
22+
coercion all the elements must be non-negative and not \code{NA}.}
2223
}
2324
\details{
2425
The functions \code{dim} and \code{dim<-} are \link{internal generic}
@@ -34,8 +35,8 @@ dim(x) <- value
3435
of mode \code{\link{integer}}.
3536

3637
The replacement method changes the \code{"dim"} attribute (provided the
37-
new value is compatible) and removes any \code{"dimnames"} \emph{and}
38-
\code{"names"} attributes.
38+
new value is compatible with the length) and removes any
39+
\code{"dimnames"} \emph{and} \code{"names"} attributes.
3940
}
4041
\references{
4142
\bibshow{R:Becker+Chambers+Wilks:1988}

src/main/array.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -290,16 +290,19 @@ R_xlen_t dim2total(SEXP dim /* INTSXP */, bool *err)
290290
int d;
291291

292292
d = INTEGER(dim)[i];
293-
/* Actually, NA_INTEGER is < 0, so we don't need to test for it
293+
/* dn *= d can overflow, but the result is 0 if any dimension is
294+
* (unless NA, so we can't simply break here).
295+
*/
296+
if (d == 0)
297+
dn = 0.0;
298+
/* Actually, NA_INTEGER is < 0, so we don't need to test for it
294299
explicitly, but the value might change, so better be safe...
295300
An optimizing compiler will likely strip the && part.
296301
*/
297-
// this can overflow, but the result is 0 if any dimenston is.
298-
if (d == 0)
299-
dn = 0.0;
300-
else if (d >= 0 && d != NA_INTEGER)
302+
if (d >= 0 && d != NA_INTEGER) {
301303
dn *= d;
302-
else {
304+
// Better to check for total here to avoid f/p overflow.
305+
} else {
303306
if (d == NA_INTEGER)
304307
error(_("the dims contain missing values"));
305308
else
@@ -311,7 +314,7 @@ R_xlen_t dim2total(SEXP dim /* INTSXP */, bool *err)
311314
#else
312315
if (dn > INT_MAX)
313316
#endif
314-
*err = true;
317+
*err = true; // and callers should not use the return value.
315318
return (R_xlen_t) dn;
316319
}
317320

tests/reg-tests-1e.R

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3667,6 +3667,8 @@ for(nd in c(2:4, 33:37)) {
36673667
stopifnot(identical(x, y), is.integer(d <- dim(x)), all.equal(d., d))
36683668
}
36693669
## above creation of x & y failed for a couple of hours in R-devel
3670+
## r90452 overflowed the computation of the product of dimeensions.
3671+
## giving a negative answer on some platforms (x86_64, not macOS).
36703672

36713673

36723674
## PR#19116 -- <matrix>[[i, j]]: stochastic error with negative i
@@ -3684,7 +3686,7 @@ save("save", file=(tf <- tempfile("saveRdata")))
36843686
sys.load.image(tf, FALSE); rm(tf, save)
36853687
## had called .Internal(RNGkind(..)) with wrong number of args
36863688

3687-
## aperm and
3689+
## aperm and
36883690
m <- matrix(1:10, 2, 5, dimnames = list(X = paste0("x", 1:2), Y = paste0("y", 1:5)))
36893691
a <- array(m, dim = c(2, 5, 1), dimnames = list(X = paste0("x", 1:2), Y = paste0("y", 1:5), Z = "z1"))
36903692

0 commit comments

Comments
 (0)