Re: [Rd] longint

2018-08-15 Thread William Dunlap via R-devel
Note that include/S.h contains
  /*
 This is a legacy header and no longer documented.
 Code using it should be converted to use R.h
  */
  ...
  /* is this a good idea? - conflicts with many versions of f2c.h */
  # define longint int

S.h was meant to be used while converting to R C code written for S or S+.
S/S+ "integers" are represented as C "long ints", whose size depends on
the architecture, while R "integers" are represented as 32-bit C "ints".
"longint" was invented to hide this difference.


Bill Dunlap
TIBCO Software
wdunlap tibco.com

On Wed, Aug 15, 2018 at 5:32 PM, Benjamin Tyner  wrote:

> Thanks for the replies and for confirming my suspicion.
>
> Interestingly, src/include/S.h uses a trick:
>
>#define longint int
>
> and so does the nlme package (within src/init.c).
>
> On 08/15/2018 02:47 PM, Hervé Pagès wrote:
>
>> No segfault but a BIG warning from the compiler. That's because
>> dereferencing the pointer inside your myfunc() function will
>> produce an int that is not predictable i.e. it is system-dependent.
>> Its value will depend on sizeof(long int) (which is not
>> guaranteed to be 8) and on the endianness of the system.
>>
>> Also if the pointer you pass in the call to the function is
>> an array of long ints, then pointer arithmetic inside your myfunc()
>> won't necessarily take you to the array element that you'd expect.
>>
>> Note that there are very specific situations where you can actually
>> do this kind of things e.g. in the context of writing a callback
>> function to pass to qsort(). See 'man 3 qsort' if you are on a Unix
>> system. In that case pointers to void and explicit casts should
>> be used. If done properly, this is portable code and the compiler won't
>> issue warnings.
>>
>> H.
>>
>>
>> On 08/15/2018 07:05 AM, Brian Ripley wrote:
>>
>>>
>>>
>>> On 15 Aug 2018, at 12:48, Duncan Murdoch 
 wrote:

 On 15/08/2018 7:08 AM, Benjamin Tyner wrote:
> Hi
> In my R package, imagine I have a C function defined:
>  void myfunc(int *x) {
> // some code
>  }
> but when I call it, I pass it a pointer to a longint instead of a
> pointer to an int. Could this practice potentially result in a
> segfault?
>

 I don't think the passing would cause a segfault, but "some code" might
 be expecting a positive number, and due to the type error you could pass in
 a positive longint and have it interpreted as a negative int.

>>>
>>> Are you thinking only of a little-endian system?  A 32-bit lookup of a
>>> pointer to a 64-bit area could read the wrong half and get a completely
>>> different value.
>>>
>>>
 Duncan Murdoch

 __
 R-devel@r-project.org mailing list
 https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.et
 hz.ch_mailman_listinfo_r-2Ddevel=DwIFAg=eRAMFD45gAfqt84V
 tBcfhQ=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA=ERck0
 y30d00Np6hqTNYfjusx1beZim0OrKe9O4vkUxU=x1gI9ACZol7WbaWQ7Oc
 v60csJFJClZotWkJIMwUdjIc=

>>>
>>> __
>>> R-devel@r-project.org mailing list
>>> https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.et
>>> hz.ch_mailman_listinfo_r-2Ddevel=DwIFAg=eRAMFD45gAfqt84V
>>> tBcfhQ=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA=ERck0
>>> y30d00Np6hqTNYfjusx1beZim0OrKe9O4vkUxU=x1gI9ACZol7WbaWQ7Oc
>>> v60csJFJClZotWkJIMwUdjIc=
>>>
>>>
>>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] longint

2018-08-15 Thread Benjamin Tyner

Thanks for the replies and for confirming my suspicion.

Interestingly, src/include/S.h uses a trick:

   #define longint int

and so does the nlme package (within src/init.c).

On 08/15/2018 02:47 PM, Hervé Pagès wrote:
No segfault but a BIG warning from the compiler. That's because 
dereferencing the pointer inside your myfunc() function will

produce an int that is not predictable i.e. it is system-dependent.
Its value will depend on sizeof(long int) (which is not
guaranteed to be 8) and on the endianness of the system.

Also if the pointer you pass in the call to the function is
an array of long ints, then pointer arithmetic inside your myfunc()
won't necessarily take you to the array element that you'd expect.

Note that there are very specific situations where you can actually
do this kind of things e.g. in the context of writing a callback
function to pass to qsort(). See 'man 3 qsort' if you are on a Unix
system. In that case pointers to void and explicit casts should
be used. If done properly, this is portable code and the compiler won't
issue warnings.

H.


On 08/15/2018 07:05 AM, Brian Ripley wrote:



On 15 Aug 2018, at 12:48, Duncan Murdoch  
wrote:



On 15/08/2018 7:08 AM, Benjamin Tyner wrote:
Hi
In my R package, imagine I have a C function defined:
 void myfunc(int *x) {
    // some code
 }
but when I call it, I pass it a pointer to a longint instead of a
pointer to an int. Could this practice potentially result in a 
segfault?


I don't think the passing would cause a segfault, but "some code" 
might be expecting a positive number, and due to the type error you 
could pass in a positive longint and have it interpreted as a 
negative int.


Are you thinking only of a little-endian system?  A 32-bit lookup of 
a pointer to a 64-bit area could read the wrong half and get a 
completely different value.




Duncan Murdoch

__
R-devel@r-project.org mailing list
https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.ethz.ch_mailman_listinfo_r-2Ddevel=DwIFAg=eRAMFD45gAfqt84VtBcfhQ=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA=ERck0y30d00Np6hqTNYfjusx1beZim0OrKe9O4vkUxU=x1gI9ACZol7WbaWQ7Ocv60csJFJClZotWkJIMwUdjIc= 



__
R-devel@r-project.org mailing list
https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.ethz.ch_mailman_listinfo_r-2Ddevel=DwIFAg=eRAMFD45gAfqt84VtBcfhQ=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA=ERck0y30d00Np6hqTNYfjusx1beZim0OrKe9O4vkUxU=x1gI9ACZol7WbaWQ7Ocv60csJFJClZotWkJIMwUdjIc= 







__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] longint

2018-08-15 Thread Hervé Pagès
No segfault but a BIG warning from the compiler. That's because 
dereferencing the pointer inside your myfunc() function will

produce an int that is not predictable i.e. it is system-dependent.
Its value will depend on sizeof(long int) (which is not
guaranteed to be 8) and on the endianness of the system.

Also if the pointer you pass in the call to the function is
an array of long ints, then pointer arithmetic inside your myfunc()
won't necessarily take you to the array element that you'd expect.

Note that there are very specific situations where you can actually
do this kind of things e.g. in the context of writing a callback
function to pass to qsort(). See 'man 3 qsort' if you are on a Unix
system. In that case pointers to void and explicit casts should
be used. If done properly, this is portable code and the compiler won't
issue warnings.

H.


On 08/15/2018 07:05 AM, Brian Ripley wrote:




On 15 Aug 2018, at 12:48, Duncan Murdoch  wrote:


On 15/08/2018 7:08 AM, Benjamin Tyner wrote:
Hi
In my R package, imagine I have a C function defined:
 void myfunc(int *x) {
// some code
 }
but when I call it, I pass it a pointer to a longint instead of a
pointer to an int. Could this practice potentially result in a segfault?


I don't think the passing would cause a segfault, but "some code" might be 
expecting a positive number, and due to the type error you could pass in a positive 
longint and have it interpreted as a negative int.


Are you thinking only of a little-endian system?  A 32-bit lookup of a pointer 
to a 64-bit area could read the wrong half and get a completely different value.



Duncan Murdoch

__
R-devel@r-project.org mailing list
https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.ethz.ch_mailman_listinfo_r-2Ddevel=DwIFAg=eRAMFD45gAfqt84VtBcfhQ=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA=ERck0y30d00Np6hqTNYfjusx1beZim0OrKe9O4vkUxU=x1gI9ACZol7WbaWQ7Ocv60csJFJClZotWkJIMwUdjIc=


__
R-devel@r-project.org mailing list
https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.ethz.ch_mailman_listinfo_r-2Ddevel=DwIFAg=eRAMFD45gAfqt84VtBcfhQ=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA=ERck0y30d00Np6hqTNYfjusx1beZim0OrKe9O4vkUxU=x1gI9ACZol7WbaWQ7Ocv60csJFJClZotWkJIMwUdjIc=



--
Hervé Pagès

Program in Computational Biology
Division of Public Health Sciences
Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N, M1-B514
P.O. Box 19024
Seattle, WA 98109-1024

E-mail: hpa...@fredhutch.org
Phone:  (206) 667-5791
Fax:(206) 667-1319

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] validspamobject?

2018-08-15 Thread William Dunlap via R-devel
That was my first thought (my second was trace(.Deprecated,...)).  However,
the spam authors don't use .Deprecated() or warning() to tell about
deprecated functions.  See spam/R/deprecated.R:

validspamobject <- function( ...) {
#.Deprecated('validate_spam()')
message("`validspamobject()` is deprecated. Use `validate_spam()`
directly")
validate_spam( ...)
}

spam.getOption <- function(...) {
#.Deprecated(msg="`spam.getOption( arg)` is deprecated.\n Use
`getOption( spam.arg)` directly")
message("`spam.getOption( arg)` is deprecated. Use `getOption(
spam.arg)` directly")
getOption(...)

}



Bill Dunlap
TIBCO Software
wdunlap tibco.com

On Wed, Aug 15, 2018 at 1:26 AM, Emil Bode  wrote:

> Hello,
>
> If you want to determine where the warning is generated, I think it's
> easiest to run R with options(warn=2).
> In that case all warnings are converted to errors, and you have more
> debugging tools, e.g. you can run traceback() to see the calling stack, or
> use options(error=recover).
> Hope you can catch it.
>
>
> Best regards,
> Emil Bode
>
> is an institute of the Dutch Academy KNAW  and funding
> organisation NWO .
>
> On 15/08/2018, 02:57, "R-devel on behalf of Ronald Barry" <
> r-devel-boun...@r-project.org on behalf of rpba...@alaska.edu> wrote:
>
> Greetings,
>   My R package has been showing warnings of the form:
>
> `validspamobject()` is deprecated. Use `validate_spam()` directly
>
> None of my code uses the function validspamobject, so it must be a
> problem
> in another package I'm calling, possibly spam or spdep.  Has this
> problem
> occurred with other people?  It doesn't have any deleterious effect,
> but
> it's annoying.  In particular, how do I determine which package is
> causing
> this warning?  Thanks.
>
> Ron B.
>
> [[alternative HTML version deleted]]
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] longint

2018-08-15 Thread Brian Ripley



> On 15 Aug 2018, at 12:48, Duncan Murdoch  wrote:
> 
>> On 15/08/2018 7:08 AM, Benjamin Tyner wrote:
>> Hi
>> In my R package, imagine I have a C function defined:
>> void myfunc(int *x) {
>>// some code
>> }
>> but when I call it, I pass it a pointer to a longint instead of a
>> pointer to an int. Could this practice potentially result in a segfault?
> 
> I don't think the passing would cause a segfault, but "some code" might be 
> expecting a positive number, and due to the type error you could pass in a 
> positive longint and have it interpreted as a negative int.

Are you thinking only of a little-endian system?  A 32-bit lookup of a pointer 
to a 64-bit area could read the wrong half and get a completely different value.

> 
> Duncan Murdoch
> 
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] substitute() on arguments in ellipsis ("dot dot dot")?

2018-08-15 Thread Jim Hester
Assuming you are fine with a pairlist instead of a list avoiding the
`as.list()` call for dots2 saves a reasonable amount of time and makes it
clearly the fastest.

library(rlang)

dots1 <- function(...) as.list(substitute(list(...)))[-1L]
dots2 <- function(...) as.list(substitute(...()))
dots2.5 <- function(...) substitute(...())
dots3 <- function(...) match.call(expand.dots = FALSE)[["..."]]
dots4 <- function(...) exprs(...)

bench::mark(
  dots1(1+2, "a", rnorm(3), stop("bang!")),
  dots2(1+2, "a", rnorm(3), stop("bang!")),
  dots2.5(1+2, "a", rnorm(3), stop("bang!")),
  dots3(1+2, "a", rnorm(3), stop("bang!")),
  dots4(1+2, "a", rnorm(3), stop("bang!")),
  check = FALSE
)[1:4]
#> # A tibble: 5 x 4
#>   expression min mean
 median
#> 

#> 1 "dots1(1 + 2, \"a\", rnorm(3), stop(\"bang!\…   2.38µs   5.63µs
 2.89µs
#> 2 "dots2(1 + 2, \"a\", rnorm(3), stop(\"bang!\…   2.07µs3.1µs
2.6µs
#> 3 "dots2.5(1 + 2, \"a\", rnorm(3), stop(\"bang…471ns  789.5ns
638ns
#> 4 "dots3(1 + 2, \"a\", rnorm(3), stop(\"bang!\…   3.17µs   4.83µs
 4.22µs
#> 5 "dots4(1 + 2, \"a\", rnorm(3), stop(\"bang!\…   3.16µs   4.43µs
 3.87µs


On Mon, Aug 13, 2018 at 7:59 PM Hadley Wickham  wrote:

> Since you're already using bang-bang ;)
>
> library(rlang)
>
> dots1 <- function(...) as.list(substitute(list(...)))[-1L]
> dots2 <- function(...) as.list(substitute(...()))
> dots3 <- function(...) match.call(expand.dots = FALSE)[["..."]]
> dots4 <- function(...) exprs(...)
>
> bench::mark(
>   dots1(1+2, "a", rnorm(3), stop("bang!")),
>   dots2(1+2, "a", rnorm(3), stop("bang!")),
>   dots3(1+2, "a", rnorm(3), stop("bang!")),
>   dots4(1+2, "a", rnorm(3), stop("bang!")),
>   check = FALSE
> )[1:4]
> #> # A tibble: 4 x 4
> #>   expression  min mean
> median
> #>  
> 
> #> 1 "dots1(1 + 2, \"a\", rnorm(3), stop(\"bang!\"…   3.23µs   4.15µs
> 3.81µs
> #> 2 "dots2(1 + 2, \"a\", rnorm(3), stop(\"bang!\"…   2.72µs   4.48µs
> 3.37µs
> #> 3 "dots3(1 + 2, \"a\", rnorm(3), stop(\"bang!\"…   4.06µs   4.94µs
> 4.69µs
> #> 4 "dots4(1 + 2, \"a\", rnorm(3), stop(\"bang!\"…   3.92µs4.9µs
> 4.46µs
>
>
> On Mon, Aug 13, 2018 at 4:19 AM Henrik Bengtsson
>  wrote:
> >
> > Thanks all, this was very helpful.  Peter's finding - dots2() below -
> > is indeed interesting - I'd be curious to learn what goes on there.
> >
> > The different alternatives perform approximately the same;
> >
> > dots1 <- function(...) as.list(substitute(list(...)))[-1L]
> > dots2 <- function(...) as.list(substitute(...()))
> > dots3 <- function(...) match.call(expand.dots = FALSE)[["..."]]
> >
> > stats <- microbenchmark::microbenchmark(
> >   dots1(1+2, "a", rnorm(3), stop("bang!")),
> >   dots2(1+2, "a", rnorm(3), stop("bang!")),
> >   dots3(1+2, "a", rnorm(3), stop("bang!")),
> >   times = 10e3
> > )
> > print(stats)
> > # Unit: microseconds
> > #expr  min   lq mean median
> > uq  max neval
> > #  dots1(1 + 2, "a", rnorm(3), stop("bang!")) 2.14 2.45 3.04   2.58
> > 2.73 1110 1
> > #  dots2(1 + 2, "a", rnorm(3), stop("bang!")) 1.81 2.10 2.47   2.21
> > 2.34 1626 1
> > #  dots3(1 + 2, "a", rnorm(3), stop("bang!")) 2.59 2.98 3.36   3.15
> > 3.31 1037 1
> >
> > /Henrik
> >
> > On Mon, Aug 13, 2018 at 7:10 AM Peter Meilstrup
> >  wrote:
> > >
> > > Interestingly,
> > >
> > >as.list(substitute(...()))
> > >
> > > also works.
> > >
> > > On Sun, Aug 12, 2018 at 1:16 PM, Duncan Murdoch
> > >  wrote:
> > > > On 12/08/2018 4:00 PM, Henrik Bengtsson wrote:
> > > >>
> > > >> Hi. For any number of *known* arguments, we can do:
> > > >>
> > > >> one <- function(a) list(a = substitute(a))
> > > >> two <- function(a, b) list(a = substitute(a), b = substitute(b))
> > > >>
> > > >> and so on. But how do I achieve the same when I have:
> > > >>
> > > >> dots <- function(...) list(???)
> > > >>
> > > >> I want to implement this such that I can do:
> > > >>
> > > >>> exprs <- dots(1+2)
> > > >>> str(exprs)
> > > >>
> > > >> List of 1
> > > >>   $ : language 1 + 2
> > > >>
> > > >> as well as:
> > > >>
> > > >>> exprs <- dots(1+2, "a", rnorm(3))
> > > >>> str(exprs)
> > > >>
> > > >> List of 3
> > > >>   $ : language 1 + 2
> > > >>   $ : chr "a"
> > > >>   $ : language rnorm(3)
> > > >>
> > > >> Is this possible to achieve using plain R code?
> > > >
> > > >
> > > > I think so.  substitute(list(...)) gives you a single expression
> containing
> > > > a call to list() with the unevaluated arguments; you can convert
> that to
> > > > what you want using something like
> > > >
> > > > dots <- function (...) {
> > > >   exprs <- substitute(list(...))
> > > >   as.list(exprs[-1])
> > > > }
> > > >
> > > > Duncan Murdoch
> > > >
> > > >
> > > > __
> > > > R-devel@r-project.org mailing list
> > > > 

Re: [Rd] longint

2018-08-15 Thread Duncan Murdoch

On 15/08/2018 7:08 AM, Benjamin Tyner wrote:

Hi

In my R package, imagine I have a C function defined:

     void myfunc(int *x) {
    // some code
     }

but when I call it, I pass it a pointer to a longint instead of a
pointer to an int. Could this practice potentially result in a segfault?


I don't think the passing would cause a segfault, but "some code" might 
be expecting a positive number, and due to the type error you could pass 
in a positive longint and have it interpreted as a negative int.


Duncan Murdoch

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


[Rd] longint

2018-08-15 Thread Benjamin Tyner

Hi

In my R package, imagine I have a C function defined:

   void myfunc(int *x) {
  // some code
   }

but when I call it, I pass it a pointer to a longint instead of a 
pointer to an int. Could this practice potentially result in a segfault?


Regards
Ben

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] validspamobject?

2018-08-15 Thread Emil Bode
Hello,

If you want to determine where the warning is generated, I think it's easiest 
to run R with options(warn=2).
In that case all warnings are converted to errors, and you have more debugging 
tools, e.g. you can run traceback() to see the calling stack, or use 
options(error=recover).
Hope you can catch it.


Best regards, 
Emil Bode

is an institute of the Dutch Academy KNAW  and funding 
organisation NWO . 

On 15/08/2018, 02:57, "R-devel on behalf of Ronald Barry" 
 wrote:

Greetings,
  My R package has been showing warnings of the form:

`validspamobject()` is deprecated. Use `validate_spam()` directly

None of my code uses the function validspamobject, so it must be a problem
in another package I'm calling, possibly spam or spdep.  Has this problem
occurred with other people?  It doesn't have any deleterious effect, but
it's annoying.  In particular, how do I determine which package is causing
this warning?  Thanks.

Ron B.

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] substitute() on arguments in ellipsis ("dot dot dot")?

2018-08-15 Thread lmo via R-devel
A potential solution, at least in terms of producing the desired output, is the 
base R function alist:
> alist(1+2, "a", rnorm(3))
[[1]]
1 + 2

[[2]]
[1] "a"

[[3]]
rnorm(3)

> str(alist(1+2, "a", rnorm(3)))
List of 3
 $ : language 1 + 2
 $ : chr "a"
 $ : language rnorm(3)


luke

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel